1. 程式人生 > >[NOIP補坑計劃]NOIP2014 題解&做題心得

[NOIP補坑計劃]NOIP2014 題解&做題心得

六道普及組題,沒啥好說的

場上預計得分:100+100+100+100+100+100=600(省一分數線490)

(AK是不可能AK的,這輩子不可能AK的)

題解:

D1T1 生活大爆炸版石頭剪刀布

題面

水題送溫暖~

 1 #include<algorithm>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<cstdio>
 5 #include<cmath>
 6 #include<queue>
 7 #define inf 2147483647
 8
#define eps 1e-9 9 using namespace std; 10 typedef long long ll; 11 const int ch[5][5]={{0,0,1,1,0},{1,0,0,1,0},{0,1,0,0,1},{0,0,1,0,1},{1,1,0,0,0}}; 12 int n,n1,n2,ans1,ans2,a[201],b[201]; 13 int main(){ 14 scanf("%d%d%d",&n,&n1,&n2); 15 for(int i=0;i<n1;i++){ 16 scanf("%d",&a[i]);
17 } 18 for(int i=0;i<n2;i++){ 19 scanf("%d",&b[i]); 20 } 21 for(int i=1;i<=n;i++){ 22 ans1+=ch[a[(i-1)%n1]][b[(i-1)%n2]]; 23 ans2+=ch[b[(i-1)%n2]][a[(i-1)%n1]]; 24 } 25 printf("%d %d",ans1,ans2); 26 return 0; 27 }

D1T2 聯合權值

題面

和一個同點相連的兩個點一定會產生聯合權值;

 1 #include<algorithm>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<cstdio>
 5 #include<cmath>
 6 #include<queue>
 7 #define inf 2147483647
 8 #define eps 1e-9
 9 #define mod 10007
10 using namespace std;
11 typedef long long ll;
12 struct edge{
13     int v,next;
14 }a[500001];
15 int n,u,v,tot=0,ans=-inf,anss=0,top,s[200001],num[200001],head[200001];
16 void add(int u,int v){
17     a[++tot].v=v;
18     a[tot].next=head[u];
19     head[u]=tot;
20 }
21 void work(int u){
22     int sum=0,mx=-inf,mmx=-inf;
23     top=0;
24     for(int tmp=head[u];tmp!=-1;tmp=a[tmp].next){
25         int v=a[tmp].v;
26         s[++top]=v;
27         sum+=num[v];
28         if(num[v]>mx){
29             mmx=mx;
30             mx=num[v];
31         }else mmx=max(mmx,num[v]);
32     }
33     if(top<2)return;
34     ans=max(ans,mx*mmx);
35     for(int i=1;i<=top;i++){
36         anss=(anss+(ll)num[s[i]]*(sum-num[s[i]]))%mod;
37     }
38 }
39 int main(){
40     memset(head,-1,sizeof(head));
41     scanf("%d",&n);
42     for(int i=1;i<n;i++){
43         scanf("%d%d",&u,&v);
44         add(u,v);
45         add(v,u);
46     }
47     for(int i=1;i<=n;i++)scanf("%d",&num[i]);
48     for(int i=1;i<=n;i++){
49         work(i);
50     }
51     printf("%d %d",ans,anss);
52     return 0;
53 }

D1T3 飛揚的小鳥

題面

唯一可能有點思維難度的題?70分顯然,然後向上向下分兩種揹包(01和完全)轉移即可;

(1A爽爽)

 1 #include<algorithm>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<cstdio>
 5 #include<cmath>
 6 #include<queue>
 7 #define inf 0x7f7f7f7f
 8 #define eps 1e-9
 9 using namespace std;
10 typedef long long ll;
11 int n,m,k,p,L,H,tmp,ans=inf,x[10001],y[10001],l[10001],h[10001],f[10001][1001];
12 bool isp[10001];
13 int main(){
14     memset(f,0x7f,sizeof(f));
15     memset(isp,0,sizeof(isp));
16     scanf("%d%d%d",&n,&m,&k);
17     for(int i=1;i<=n;i++){
18         scanf("%d%d",&x[i],&y[i]);
19         l[i]=0;
20         h[i]=m+1;
21     }
22     for(int i=1;i<=k;i++){
23         scanf("%d%d%d",&p,&L,&H);
24         isp[p]=true;
25         l[p]=L;
26         h[p]=H;
27     }
28     for(int i=1;i<=m;i++)f[0][i]=0;
29     for(int i=1;i<=n;i++){
30         for(int j=x[i]+1;j<=m;j++){
31             f[i][j]=min(f[i][j],f[i-1][j-x[i]]+1);
32             f[i][j]=min(f[i][j],f[i][j-x[i]]+1);
33         }
34         for(int j=m-x[i];j<=m;j++){
35             f[i][m]=min(f[i][m],min(f[i][j]+1,f[i-1][j]+1));
36         }
37         for(int j=l[i]+1;j<h[i];j++){
38             if(j+y[i]<=m){
39                 f[i][j]=min(f[i][j],f[i-1][j+y[i]]);
40             }
41         }
42         for(int j=0;j<=l[i];j++)f[i][j]=inf;
43         for(int j=h[i];j<=m;j++)f[i][j]=inf;
44     }
45     for(int i=1;i<=m;i++){
46         ans=min(ans,f[n][i]);
47     }
48     if(ans==inf){
49         ans=0;
50         for(int i=1;i<=n;i++){
51             tmp=inf;
52             for(int j=1;j<=m;j++)tmp=min(tmp,f[i][j]);
53             if(tmp==inf)break;
54             if(isp[i])ans++;
55         }
56         printf("0\n%d",ans);
57     }else printf("1\n%d",ans);
58     return 0;
59 }

D2T1 無線網路發射器選址

題面

水題送溫暖~

 1 #include<algorithm>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<cstdio>
 5 #include<cmath>
 6 #include<queue>
 7 #define inf 2147483647
 8 #define eps 1e-9
 9 using namespace std;
10 typedef long long ll;
11 int n,d,x,y,k,ans=0,tmp,anss=0,mp[201][201];
12 int main(){
13     scanf("%d%d",&d,&n);
14     for(int i=1;i<=n;i++){
15         scanf("%d%d%d",&x,&y,&k);
16         mp[x][y]=k;
17     }
18     for(int i=0;i<=128;i++){
19         for(int j=0;j<=128;j++){
20             tmp=0;
21             for(int x=max(i-d,0);x<=min(i+d,128);x++){
22                 for(int y=max(j-d,0);y<=min(j+d,128);y++){
23                     tmp+=mp[x][y];
24                 }
25             }
26             if(tmp>ans){
27                 ans=tmp;
28                 anss=1;
29             }else if(tmp==ans)anss++;
30         }
31     }
32     printf("%d %d",anss,ans);
33     return 0;
34 }

D2T2 尋找道路

題面

什麼時候裸的最短路可以上D2T2了??顯然建反向邊把不能到達的點判掉,然後裸的最短路;

(並沒有卡SPFA好評)

 1 #include<algorithm>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<cstdio>
 5 #include<cmath>
 6 #include<queue>
 7 #define inf 2147483647
 8 #define eps 1e-9
 9 using namespace std;
10 typedef long long ll;
11 struct edge{
12     int v,next;
13 }a[200001],_a[200001];
14 int n,m,u,v,vs,vt,tot=0,_tot=0,head[100001],_head[100001],sp[100001];
15 bool isin[100001],used[100001],vis[100001];
16 void add(int u,int v){
17     a[++tot].v=v;
18     a[tot].next=head[u];
19     head[u]=tot;
20 }
21 void _add(int u,int v){
22     _a[++_tot].v=v;
23     _a[_tot].next=_head[u];
24     _head[u]=_tot;
25 }
26 void bfs(int s){
27     queue<int>q;
28     q.push(s);
29     used[s]=true;
30     while(!q.empty()){
31         int u=q.front();
32         q.pop();
33         for(int tmp=_head[u];tmp!=-1;tmp=_a[tmp].next){
34             int v=_a[tmp].v;
35             if(!used[v]){
36                 used[v]=true;
37                 q.push(v);
38             }
39         }
40     }
41 }
42 void spfa(int s){
43     memset(isin,0,sizeof(isin));
44     memset(sp,0x3f,sizeof(sp));
45     queue<int>q;
46     q.push(s);
47     isin[s]=true;
48     sp[s]=0;
49     while(!q.empty()){
50         int u=q.front();
51         q.pop();
52         isin[u]=false;
53         for(int tmp=head[u];tmp!=-1;tmp=a[tmp].next){
54             int v=a[tmp].v;
55             if(vis[v]&&sp[v]>sp[u]+1){
56                 sp[v]=sp[u]+1;
57                 if(!isin[v]){
58                     isin[v]=true;
59                     q.push(v);
60                 }
61             }
62         }
63     }
64 }
65 int main(){
66     memset(used,0,sizeof(used));
67     memset(head,-1,sizeof(head));
68     memset(_head,-1,sizeof(_head));
69     scanf("%d%d",&n,&m);
70     for(int i=1;i<=m;i++){
71         scanf("%d%d",&u,&v);
72         if(u==v)continue;
73         add(u,v);
74         _add(v,u);
75     }
76     scanf("%d%d",&vs,&vt);
77     bfs(vt);
78     if(!used[vs])return printf("-1"),0;
79     for(int i=1;i<=n;i++){
80         vis[i]=true;
81         for(int tmp=head[i];tmp!=-1;tmp=a[tmp].next){
82             int v=a[tmp].v;
83             vis[i]&=used[v];
84         }
85     }
86     spfa(vs);
87     printf("%d",sp[vt]);
88     return 0;
89 }

D2T3 解方程

題面

無力吐槽了……一道跟D1T1一樣水的題放在D2T3是想考我們讀題能力嗎……還是考字串轉化成數字的處理??

列舉解,把所有係數膜一個大質數即可;

 1 #include<algorithm>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<cstdio>
 5 #include<cmath>
 6 #include<queue>
 7 #define inf 2147483647
 8 #define eps 1e-9
 9 #define mod 998244353
10 using namespace std;
11 typedef long long ll;
12 int rd(){
13     int x=0,f=1;
14     char ch;
15     do{
16         ch=getchar();
17         if(ch=='-')f=-1;
18     }while(!isdigit(ch));
19     do{
20         x=((ll)x*10+ch-'0')%mod;
21         ch=getchar();
22     }while(isdigit(ch));
23     if(f==-1)x=mod-x;
24     return x;
25 }
26 int n,m,ans=0,anss[100001],num[101];
27 void work(int x){
28     ll nw=1,ret=0;
29     for(int i=0;i<=n;i++){
30         ret=(ret+(ll)nw*num[i]%mod+mod)%mod;
31         nw=(nw*x)%mod;
32     }
33     if(ret==0)anss[++ans]=x;
34 }
35 int main(){
36     scanf("%d%d",&n,&m);
37     for(int i=0;i<=n;i++){
38         num[i]=rd();
39     }
40     for(int i=1;i<=m;i++){
41         work(i);
42     }
43     printf("%d\n",ans);
44     for(int i=1;i<=ans;i++){
45         printf("%d\n",anss[i]);
46     }
47     return 0;
48 }

總結:

早就聽說很水,沒想到這麼水……晚上無聊寫寫一個半小時不到寫完了……“當你走進提高組考場考了六道普及組題目是怎樣一種體驗”