【NOIp】NOIp2014
NOIp 2014
day 1 T1 生活大爆炸版石头剪刀布
标签:模拟
code(巨丑
1 #include <iostream>
2 #include <cstdio>
3 using namespace std;
4 int main(){
5 int n,na,nb,x,y,xa[201],xb[201],i,j,a,ans,bns;
6 cin>>n>>na>>nb;
7 for(i=1;i<=na;i++){
8 cin>>x;
9 xa[i]=x;
10 }
11 for(j=1;j<=nb;j++){
12 cin>>y;
13 xb[j]=y;
14 }
15 ans=0;bns=0;
16 i=0;j=0;
17 for(a=1;a<=n;a++){
18 i++;j++;
19 if(i>na)i=1;
20 if(j>nb)j=1;
21 if(xa[i]==0&&xb[j]==1)bns++;
22 if(xa[i]==0&&xb[j]==2)ans++;
23 if(xa[i]==0&&xb[j]==3)ans++;
24 if(xa[i]==0&&xb[j]==4)bns++;
25 if(xa[i]==1&&xb[j]==0)ans++;
26 if(xa[i]==1&&xb[j]==2)bns++;
27 if(xa[i]==1&&xb[j]==3)ans++;
28 if(xa[i]==1&&xb[j]==4)bns++;
29 if(xa[i]==2&&xb[j]==0)bns++;
30 if(xa[i]==2&&xb[j]==1)ans++;
31 if(xa[i]==2&&xb[j]==3)bns++;
32 if(xa[i]==2&&xb[j]==4)ans++;
33 if(xa[i]==3&&xb[j]==0)bns++;
34 if(xa[i]==3&&xb[j]==1)bns++;
35 if(xa[i]==3&&xb[j]==2)ans++;
36 if(xa[i]==3&&xb[j]==4)ans++;
37 if(xa[i]==4&&xb[j]==0)ans++;
38 if(xa[i]==4&&xb[j]==1)ans++;
39 if(xa[i]==4&&xb[j]==2)bns++;
40 if(xa[i]==4&&xb[j]==3)bns++;
41 }
42 cout<<ans<<" "<<bns;
43 return 0;
44 }
T1
day 1 T2 联合权值
标签:dp
转化:
step 1: 无向图,n个点,n-1条边 => 一棵树
step 2: 距离为2 => 和同一个点相连
枚举每一个点,取任意两点组合得到乘积最大值和sum
对于一个点,线性扫过所有与他相连的点,然后动态更新目前的和与目前这些点中的最大值
再到下一个点时,将下一个点的权值与这两个值相乘
code
1 #include <bits/stdc++.h>
2 using namespace std;
3 namespace gengyf{
4 #define int long long
5 inline int read(){
6 int x=0,f=1;char s=getchar();
7 while(s<'0'||s>'9'){
if(s=='-')f=-1;s=getchar();}
8 while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
9 return f*x;
10 }
11 const int mod=10007;
12 const int maxn=2e5+10;
13 struct edge{
14 int nxt,to;
15 }e[maxn*2];
16 int head[maxn],cnt,n,w[maxn];
17 inline void add(int from,int to){
18 e[++cnt].to=to;e[cnt].nxt=head[from];head[from]=cnt;
19 }
20 int ans,maxx;
21 int main(){
22 n=read();
23 for(int i=1;i<n;i++){
24 int u,v;
25 u=read();v=read();
26 add(u,v);add(v,u);
27 }
28 for(int i=1;i<=n;i++){
29 w[i]=read();
30 }
31 for(int i=1;i<=n;i++){
32 int max1=0,max2=0,t1=0,t2=0;
33 for(int j=head[i];j;j=e[j].nxt){
34 if(w[e[j].to]>max1){
35 max2=max1;max1=w[e[j].to];
36 }
37 else if(w[e[j].to]>max2)max2=w[e[j].to];
38 t1=(t1+w[e[j].to])%mod;
39 t2=(t2+w[e[j].to]*w[e[j].to])%mod;
40 }
41 t1=t1*t1%mod;
42 ans=(ans+t1-t2+mod)%mod;
43 if(maxx<max1*max2)maxx=max1*max2;
44 }
45 printf("%lld %lld",maxx,ans);
46 return 0;
47 }
48 }
49 signed main(){
50 gengyf::main();
51 return 0;
52 }
T2
day 1 T3 飞扬的小鸟
标签:dp
上升 -> 完全背包 单位时间上升是可以叠加的
下降 -> 01背包 单位时间只能下降1次
转移:
<1>上升
<2>飞到顶上
<3>下降
<4>有柱子
上升:$f[i][j]=min(f[i][j],min(f[i-1][j-lift[i-1],f[i][j-lift[i-1]])+1)$
code
1 #include<bits/stdc++.h>
2 using namespace std;
3 #define MAXN 1<<30
4 struct Pipe{
5 int pos,up,bottom;
6 }pipe[10010];
7 int n,m,k,lift[10010],down[10010],f[10010][1010];
8 bool cmp(Pipe a,Pipe b){
9 return a.pos<b.pos;
10 }
11 int main(){
12 scanf("%d%d%d",&n,&m,&k);
13 for(int i=0;i<=n-1;i++){
14 scanf("%d%d",&lift[i],&down[i]);
15 }
16 for(int i=1;i<=k;i++){
17 scanf("%d%d%d",&pipe[i].pos,&pipe[i].bottom,&pipe[i].up);
18 }
19 sort(pipe+1,pipe+k+1,cmp);
20 for(int i=0;i<=n;i++)
21 for(int j=0;j<=m;j++){
22 f[i][j]=MAXN;
23 }
24 for(int i=1;i<=m;i++)f[0][i]=0;
25 int nump=1;
26 for(int i=1;i<=n;i++){
27 int lower=1,upper=m;
28 if(pipe[nump].pos==i){
29 upper=pipe[nump].up-1;
30 lower=pipe[nump++].bottom+1;
31 }
32 for(int j=1;j<=upper;j++){
33 for(int k=j-lift[i-1];k<=m;k++){
34 if(k>j-lift[i-1]&&j<m)break;
35 if(k>=1)f[i][j]=min(f[i][j],min(f[i-1][k],f[i][k])+1);
36 }
37 }
38 for(int j=lower;j<=upper;j++){
39 if(j+down[i-1]<=m){
40 f[i][j]=min(f[i][j],f[i-1][j+down[i-1]]);
41 }
42 }
43 for(int j=1;j<=lower-1;j++)f[i][j]=MAXN;
44 }
45 int minn=MAXN;
46 bool flag=false;
47 for(int i=n;i>=1;i--){
48 for(int j=1;j<=m;j++){
49 if(f[i][j]!=MAXN){
50 flag=true;
51 minn=min(minn,f[i][j]);
52 }
53 }
54 if(flag){
55 if(i==n){
56 printf("1\n%d",minn);
57 return 0;
58 }
59 else{
60 for(int j=k;j>=1;j--){
61 if(i>=pipe[j].pos){
62 printf("0\n%d",j);
63 return 0;
64 }
65 }
66 }
67 }
68 }
69 printf("0\n0");
70 return 0;
71 }
T3
day 2 T1 无线网络发射器选址
标签:模拟,二维前缀和
枚举每一个点,更新最大值+统计答案个数
code
1 #include <bits/stdc++.h>
2 using namespace std;
3 namespace gengyf{
4 #define ll long long
5 inline int read(){
6 int x=0,f=1;char s=getchar();
7 while(s<'0'||s>'9'){
if(s=='-')f=-1;s=getchar();}
8 while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
9 return f*x;
10 }
11 int a[130][130],n,d,s[130][130],ans,cnt;
12 int main(){
13 d=read();n=read();
14 for(int i=1;i<=n;i++){
15 int x,y,num;
16 x=read();y=read();num=read();
17 a[x][y]=num;
18 }
19 for(int i=0;i<=128;i++)
20 for(int j=0;j<=128;j++){
21 s[i][j]=s[i-1][j]+s[i][j-1]-s[i-1][j-1]+a[i][j];
22 }
23 for(int i=0;i<=128;i++)
24 for(int j=0;j<=128;j++){
25 int x1,x2,y1,y2;
26 x1=max(i-d,0);y1=max(j-d,0);
27 x2=min(i+d,128);y2=min(j+d,128);
28 int tmp=s[x2][y2]-s[x1-1][y2]-s[x2][y1-1]+s[x1-1][y1-1];
29 if(tmp==ans)cnt++;
30 else if(tmp>ans){
31 cnt=1;ans=tmp;
32 }
33 }
34 printf("%d %d",cnt,ans);
35 return 0;
36 }
37 }
38 signed main(){
39 gengyf::main();
40 return 0;
41 }
T4
day 2 T2 寻找道路
标签:图论,最短路
对于要求1可以反向建图dfs标记能到终点的点
如果标记的点,如果它的出边有未被标记的,则不合法,取消标记
对于要求2在标记的点中跑最短路
code
1 #include <bits/stdc++.h>
2 using namespace std;
3 namespace gengyf{
4 #define ll long long
5 inline int read(){
6 int x=0,f=1;char s=getchar();
7 while(s<'0'||s>'9'){
if(s=='-')f=-1;s=getchar();}
8 while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
9 return f*x;
10 }
11 const int maxn=1e4+10;
12 vector<int>G[maxn];
13 queue<int>q;
14 bool v[maxn],vis[maxn];
15 int n,m,ans[maxn],s,t;
16 int main(){
17 n=read();m=read();
18 for(int i=1;i<=m;i++){
19 int a,b;a=read();b=read();
20 if(a==b)continue;
21 G[b].push_back(a);
22 }
23 s=read();t=read();
24 v[t]=1;q.push(t);
25 while(!q.empty()){
26 int x=q.front();
27 q.pop();
28 for(int i=0;i<G[x].size();i++){
29 if(!v[G[x][i]]){
30 v[G[x][i]]=1;
31 q.push(G[x][i]);
32 }
33 }
34 }
35 memcpy(vis,v,sizeof(v));
36 for(int i=1;i<=n;i++){
37 if(!v[i]){
38 for(int j=0;j<G[i].size();j++){
39 if(vis[G[i][j]])vis[G[i][j]]=0;
40 }
41 }
42 }
43 q.push(t);
44 while(!q.empty()){
45 int x=q.front();
46 q.pop();
47 for(int i=0;i<G[x].size();i++){
48 if(vis[G[x][i]]){
49 q.push(G[x][i]);
50 vis[G[x][i]]=0;
51 ans[G[x][i]]=ans[x]+1;
52 }
53 }
54 }
55 if(ans[s]==0)puts("-1");
56 else printf("%d",ans[s]);
57 return 0;
58 }
59 }
60 signed main(){
61 gengyf::main();
62 return 0;
63 }
T5
day 2 T3 解方程
标签:数学
秦九韶算法O(n)
枚举[1,m]代入函数f(x)看是否为0,注意取模
code
1 #include <bits/stdc++.h>
2 using namespace std;
3 namespace gengyf{
4 #define ll long long
5 const int p=1e9+7;
6 const int maxn=1e6+10;
7 inline ll read(){
8 ll x=0,f=1;
9 char c=getchar();
10 while(c<'0'||c>'9'){
if(c=='-')f=-1;c=getchar();}
11 while(c>='0'&&c<='9'){x=((x*10)+c-'0')%p;c=getchar();}
12 return x*f;
13 }
14 ll sum,a[110],n,m,ans[maxn],cnt;
15 bool t=1;
16 bool calc(ll x){
17 sum=0;
18 for(ll i=n;i>=1;i--){
19 sum=((a[i]+sum)*x)%p;
20 }
21 sum=(sum+a[0])%p;
22 return !sum;
23 }
24 int main(){
25 n=read();
26 m=read();
27 for(ll i=0;i<=n;i++){
28 a[i]=read();
29 }
30 for(ll i=1;i<=m;i++){
31 if(calc(i)){
32 t=false;
33 cnt++;
34 ans[cnt]=i;
35 }
36 }
37 if(t){
38 cout<<cnt<<endl;
39 return 0;
40 }
41 printf("%lld\n",cnt);
42 for(int i=1;i<=cnt;i++){
43 printf("%lld\n",ans[i]);
44 }
45 return 0;
46 }
47 }
48 signed main(){
49 gengyf::main();
50 return 0;
51 }
T6
4102年的题真友好
转载于//www.cnblogs.com/gengyf/p/11573558.html
还没有评论,来说两句吧...