1. 程式人生 > >Test20171009 考試總結 NOIP模擬賽

Test20171009 考試總結 NOIP模擬賽

efi ges opera empty seve d+ edge algo rec

題目難度合適,區分度適中,但是本人水平不佳,沒有拿到滿意的分數。

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模擬賽