【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