Test20171009 考试总结 NOIP模拟赛
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Test20171009 考试总结 NOIP模拟赛相关的知识,希望对你有一定的参考价值。
题目难度合适,区分度适中,但是本人水平不佳,没有拿到满意的分数。
T1(matrix)
一种比较容易想到的想法是枚举起点求出最长全1串做预处理,这是O(n^2)的。
接着枚举列起点,列终点,通过后缀和维护矩形的高。这也是O(n^2)的。
实现的细节看代码:
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 5 #define max(a,b) (((a)>(b))?(a):(b)) 6 7 const int maxn = 1024; 8 9 int suf[maxn];//houzhuihe 10 int mat[maxn][maxn];//matrix 11 int len[maxn][maxn];//from some number ,the longest number 12 13 int n,m; 14 15 void read(){ 16 scanf("%d%d",&n,&m); 17 for(int i=1;i<=n;i++) 18 for(int j=1;j<=m;j++) 19 scanf("%1d",&mat[i][j]); 20 for(int i=1;i<=n;i++) 21 for(int j=m;j>=1;j--) 22 len[i][j] = (mat[i][j]==1?len[i][j+1]+1:0); 23 } 24 25 void work(){ 26 int ans = 0; 27 for(int i=1;i<=m;i++){ 28 for(int j=0;j<=1000;j++)suf[j]=0; 29 for(int j=1;j<=n;j++) suf[len[j][i]]++; 30 for(int j=1000;j>=0;j--) suf[j] = suf[j+1]+suf[j]; 31 for(int j=1;j<=1000;j++) ans = max(ans,j*suf[j]); 32 } 33 printf("%d",ans); 34 } 35 36 int main(){ 37 freopen("matrix.in","r",stdin); 38 freopen("matrix.out","w",stdout); 39 read();work();return 0; 40 }
T2(present)
这道题是一道完全背包恰好塞满的判断。对于希望达到的w,取单个价值最低的p。令剩下的构成费用x,x+kp=w.取最小的x即可。建图跑最短路。
1 #include<iostream> 2 #include<cstdio> 3 #include<queue> 4 #include<cstring> 5 #include<cstdlib> 6 #include<climits> 7 #include<algorithm> 8 using namespace std; 9 10 struct edge{ 11 int to,w; 12 }; 13 bool operator <(edge a,edge b){return a.w<b.w;} 14 15 int n,m,num,mn; 16 int p[520],a[310000]; 17 int dist[31000]; 18 vector <edge> g[11000]; 19 20 void read(){ 21 scanf("%d%d",&n,&m); 22 for(int i=1;i<=n;i++) scanf("%d",&p[i]); 23 for(int j=1;j<=m;j++) scanf("%d",&a[j]); 24 sort(p+1,p+n+1); 25 mn = p[1]; 26 } 27 28 int vis[33000]; 29 void spfa() 30 { 31 memset(dist,0x7f,sizeof(dist)); 32 queue<int> q; 33 q.push(0); 34 dist[0]=0;vis[0]=1; 35 while(!q.empty()){ 36 int x=q.front();q.pop(); 37 vis[x]=0; 38 for(int i=1;i<=n;i++){ 39 if(dist[(x+p[i])%mn]>dist[x]+p[i]){ 40 dist[(x+p[i])%mn]=dist[x]+p[i]; 41 if(!vis[(x+p[i])%mn]){ 42 q.push((x+p[i])%mn); 43 vis[(x+p[i])%mn]=1; 44 } 45 } 46 } 47 } 48 } 49 void work(){ 50 spfa(); 51 int ans=0; 52 for(int i=1;i<=m;i++){ 53 if(dist[a[i]%mn]<=a[i])ans++; 54 } 55 printf("%d",ans); 56 } 57 58 int main(){ 59 freopen("present.in","r",stdin); 60 freopen("present.out","w",stdout); 61 read(); 62 work(); 63 return 0; 64 }
T3(mahjong)
搜索简单题,期望得分100实际得分0.。。
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<algorithm> 5 #pragma GCC optimize(2) 6 using namespace std; 7 8 int tb[60],flag,what; 9 int pd_double[15]={0,1,9,11,19,21,29,31,32,33,34,35,36,37}; 10 int ans[60],num; 11 12 int str_num(char ch[]){ 13 switch(ch[1]){ 14 case ‘m‘:{return ch[0]-‘0‘;} 15 case ‘s‘:{return ch[0]-‘0‘+10;} 16 case ‘p‘:{return ch[0]-‘0‘+20;} 17 case ‘c‘:{return ch[0]-‘0‘+30;} 18 } 19 } 20 void read(){ 21 memset(tb,0,sizeof(tb)); 22 memset(ans,0,sizeof(ans)); 23 for(int i=1;i<=13;i++){ 24 char ch[4]; scanf("%s",ch); 25 tb[str_num(ch)]++; 26 } 27 } 28 29 int contry_no_double(){ 30 int etnum=0; 31 for(int i=1;i<=13;i++){ 32 if(!tb[pd_double[i]]){ 33 if(flag)return 0; else{flag = 1;what = pd_double[i];} 34 } 35 etnum+=tb[pd_double[i]]; 36 } 37 if(flag == 1&&etnum==13){ans[what] = 1;return 0;} 38 else{ 39 printf("13 1m 9m 1s 9s 1p 9p 1c 2c 3c 4c 5c 6c 7c\n"); 40 return 1; 41 } 42 } 43 void seven_double(){ 44 int dnum = 0,rec; 45 for(int i=1;i<=37;i++){ 46 if(tb[i] > 2)return; 47 if(tb[i] == 2)dnum++; 48 if(tb[i] == 1)rec = i; 49 } 50 if(dnum == 6)ans[rec]=1; 51 } 52 53 int dd[8],nd; 54 void dfs(int dep,int last,int deal){ 55 while(!tb[last]&&last<=37)last++; 56 if(deal == 13){ 57 if(flag == 1) 58 if(dd[2]==dd[1]&&nd==2){ 59 ans[what]=1;return; 60 } 61 if(flag==0){ 62 if(nd==1){ans[dd[1]]=1;return;} 63 if(nd==4){ 64 sort(dd+1,dd+5); 65 if(dd[1]==dd[2]&&dd[3]==dd[4]){ans[dd[1]]=1;ans[dd[3]]=1;} 66 if(dd[2]-dd[1]==1&&dd[3]==dd[4]&&dd[2]/10!=3){ans[dd[1]-1]=1;ans[dd[2]+1]=1;} 67 if(dd[1]==dd[2]&&dd[4]-dd[3]==1&&dd[4]/10!=3){ans[dd[4]+1]=1;ans[dd[3]-1]=1;} 68 } 69 return; 70 } 71 } 72 if(tb[last]&&tb[last+1]&&tb[last+2]&&last/10!=3){ 73 tb[last]--;tb[last+1]--;tb[last+2]--; 74 dfs(dep+1,last,deal+3); 75 tb[last]++;tb[last+1]++;tb[last+2]++; 76 } 77 if(tb[last]>=3){ 78 tb[last]-=3; 79 dfs(dep+1,last,deal+3); 80 tb[last]+=3; 81 } 82 if(nd<4){ 83 int cc[8];for(int i=1;i<=nd;i++)cc[i]=dd[i]; 84 cc[nd+1]=last; 85 sort(cc+1,cc+nd+2); 86 int fff = 0; 87 if(nd<2)fff=0; 88 if(!fff){ 89 tb[last]--;dd[++nd]=last; 90 dfs(dep+1,last,deal+1); 91 tb[last]++;nd--; 92 } 93 } 94 if(tb[last]==2&&(!flag)){ 95 tb[last]-=2;flag = 1;what = last; 96 dfs(dep+1,last+1,deal+2); 97 flag = 0;tb[last]+=2; 98 } 99 if(last%10==8||last%10==9||last/10==3)return; 100 if((bool)tb[last]+(bool)tb[last+1]+(bool)tb[last+2]==2 && (!flag)){ 101 if(!tb[last+1]){ 102 tb[last]--;tb[last+2]--;flag = 1;what=last+1; 103 dfs(dep+1,last,deal+2); 104 tb[last]++;tb[last+2]++;flag = 0; 105 } 106 if(!tb[last+2]){ 107 tb[last]--;tb[last+1]--;flag = 1;what = last+2; 108 dfs(dep+1,last,deal+2); 109 tb[last]++;tb[last+1]++;flag = 0; 110 } 111 } 112 } 113 114 void work(){ 115 flag = 0;num=0; 116 int fg = contry_no_double(); 117 if(fg)return; 118 flag = 0; 119 seven_double(); 120 dfs(1,1,0); 121 int a1=0; 122 for(int i=1;i<=37;i++){ 123 if(i%10==0)continue; 124 if(ans[i]&&tb[i]==4)ans[i]=0; 125 if(ans[i])a1++; 126 } 127 if(a1==0){puts("Nooten");} 128 else{ 129 printf("%d ",a1); 130 for(int i=1;i<=9;i++) if(ans[i])printf("%dm ",i); 131 for(int i=1;i<=9;i++) if(ans[10+i])printf("%ds ",i); 132 for(int i=1;i<=9;i++) if(ans[20+i])printf("%dp ",i); 133 for(int i=1;i<=7;i++) if(ans[30+i])printf("%dc ",i); 134 puts(""); 135 } 136 } 137 138 int main(){ 139 freopen("mahjong.in","r",stdin); 140 freopen("mahjong.out","w",stdout); 141 int t; scanf("%d",&t); 142 while(t--){read();work();} 143 return 0; 144 }
以上是关于Test20171009 考试总结 NOIP模拟赛的主要内容,如果未能解决你的问题,请参考以下文章