北京集训②DAY1 Morning

水题 最后一个非零数减1即可

 1 #include <cstdio>
 2 #include <cctype>
 3 
 4 const int MAXN=110;
 5 
 6 int n,cnt;
 7 
 8 int hh() {
 9     freopen("bit.in","r",stdin);
10     freopen("bit.out","w",stdout);
11     scanf("%d",&n);
12     cnt=1;
13     while(n) {
14         int t=n%10;
15         if(t==0) cnt*=10,n/=10;
16         else {
17             --n;
18             break;
19         }
20     }
21     printf("%d\n",n*cnt);
22     fclose(stdin);
23     fclose(stdout);
24     return 0;
25 }
26 
27 int sb=hh();
28 int main(int argc,char**argv) {;}
代码

正解是DP 然而这是可以打表找规律。。

 1 #include <cstdio>
 2 #include <cctype>
 3 
 4 int n,k,t;
 5 
 6 int a[10]={6,2,5,5,4,5,6,3,7,6};
 7 
 8 int hh() {
 9     freopen("stick.in","r",stdin);
10     freopen("stick.out","w",stdout);
11     scanf("%d",&n);
12     t=n;
13     if(n<=7) {
14         for(int i=1;i<=9;++i) if(a[i]==n) printf("%d",i);
15         goto NEXT;
16     }
17     
18     k=n%7;
19     if(k==0) while(n) printf("8"),n-=a[8];
20     
21     else if(k==2) {
22         printf("1");n-=a[1];
23         while(n) printf("8"),n-=a[8];
24     }
25     
26     else if(k==1) {
27         printf("10");n-=a[1],n-=a[0];
28         while(n) printf("8"),n-=a[8];
29     }
30     
31     else if(k==3) {
32         if(n==10) {
33             printf("22");
34             goto NEXT;
35         }
36         printf("200");n-=a[0]+a[0]+a[2];
37         while(n) printf("8"),n-=a[8];
38     }
39     
40     else if(k==4) {
41         printf("20");n-=a[2]+a[0];
42         while(n) printf("8"),n-=a[8];
43     }
44     
45     else if(k==5) {
46         printf("2");n-=a[2];
47         while(n) printf("8"),n-=a[8];
48     }
49     
50     else if(k==6) {
51         printf("6");n-=a[6];
52         while(n) printf("8"),n-=a[8];
53     }
54 NEXT:
55     printf(" ");
56     n=t;
57     t=n/2;
58     if(n-2*t<=1) --t;
59     for(int i=9;i>=1;--i) if(a[i]==(n-2*t)) {printf("%d",i);break;}
60     for(int i=1;i<=t;++i) printf("1");
61     return 0;
62 }
63 
64 int sb=hh();
65 int main(int argc,char**argv) {;}
模拟
 1 #include <cstdio>
 2 #include <cctype>
 3 
 4 int n;
 5 
 6 int s[10]={6,2,5,5,4,5,6,3,7,6};
 7 
 8 int a[100],ans[100];
 9 
10 bool pd(int x) {
11     if(x>ans[0]) return false;
12     if(x<ans[0]) {
13         ans[0]=x;
14         return true;
15     }
16     else
17       for(int i=1;i<=x;++i) {
18             if(ans[i]<a[i]) return false;
19           if(a[i]<ans[i]) return true;
20       }
21     return false;
22 }
23 
24 void DFS(int num,int cnt,int sum) {
25     if(num>9||sum==1||sum<0) return;
26     if(sum==0) {
27         if(pd(cnt)) {
28             for(int i=1;i<=cnt;++i) ans[i]=a[i];
29             ans[0]=cnt;
30         }
31         return;
32     }
33     int t=1;
34     while(sum-t*s[num]>=0) {
35         a[cnt+t]=num;
36         DFS(num+1,cnt+t,sum-t*s[num]);
37         ++t;
38     }
39     DFS(num+1,cnt,sum);
40 }
41 
42 int hh() {
43     n=61;
44     ans[0]=1e9;
45     for(int i=1;i<=9;++i) {
46         for(int j=0;j<=100;++j) a[j]=0;
47         if(n-s[i]>=0) 
48         a[1]=i,DFS(0,1,n-s[i]);
49     }    
50        printf("n==%d:",n);
51     for(int i=1;i<=ans[0];++i) printf("%d",ans[i]);
52     printf("\n");
53 }
54 
55 int sb=hh();
56 int main(int argc,char**argv) {;}
最小值搜索
 1 #include<cstdio>
 2 #include<algorithm>
 3 using namespace std;
 4 int use[8]={-1,-1,1,7,4,2,0,8};
 5 int k;
 6 long long dp[16][101];
 7 void out(long long x)
 8 {
 9     if(x/10) out(x/10);
10     putchar(x%10+'0');
11 }
12 void solve_min()
13 {
14     if(k==6) { printf("0"); return; }
15     int len=k/7+1;
16     for(int i=2;i<8;i++) dp[1][i]=use[i];
17     dp[1][6]=6;
18     if(dp[1][k]) { out(dp[1][k]); return;}
19     for(int i=2;i<=len;i++)
20     {
21         for(int j=1;j<=k;j++)
22             for(int l=2;l<=7;l++)
23             {
24                 if(j-l<=1) continue;
25                 if(!dp[i-1][j-l]) continue;
26                 if(!dp[i][j]) dp[i][j]=dp[i-1][j-l]*10+use[l];
27                 else dp[i][j]=min(dp[i][j],dp[i-1][j-l]*10+use[l]);
28             }
29         if(dp[i][k]) { out(dp[i][k]); return; }
30     }    
31 }
32 void solve_max()
33 {
34     int len=k/2;
35     if(k&1)
36     {
37         printf("7");
38         for(int i=1;i<len;i++) printf("1");
39     }
40     else 
41     {
42         for(int i=1;i<=len;i++) printf("1");
43     }
44 }
45 int main()
46 {
47     freopen("stick.in","r",stdin);
48     freopen("stick.out","w",stdout);
49     scanf("%d",&k);
50     solve_min();
51     printf(" ");
52     solve_max();
53 }
DP正解

预处理每个位置往后没有重复能扩展到的最远位置

然后枚举之前听过i首歌

整个序列分为三部分,最前面不完整部分、中间完整几段、最后面不完整部分

枚举每一段的左端点,如果他能向右扩展的部分>=这一段的右端点,说明这是合法的一段,继续下一段

如果每一段都合法,那i就合法

 1 #include <cstdio>
 2 #include <cctype>
 3 #define min(a,b) a<b?a:b
 4 
 5 const int MAXN=100010;
 6 
 7 int n,m,ans;
 8 
 9 int a[MAXN],p[MAXN];
10 
11 bool t;
12 
13 bool vis[MAXN];
14 
15 inline void read(int&x) {
16     int f=1;register char c=getchar();
17     for(x=0;!isdigit(c);c=='-'&&(f=-1),c=getchar());
18     for(;isdigit(c);x=x*10+c-48,c=getchar());
19     x=x*f;
20 }
21 
22 void pre() {
23     int r=m;
24     vis[a[m]]=true;
25     p[m]=m;
26     for(int i=m-1;i;--i) {
27         if(!vis[a[i]]) vis[a[i]]=true,p[i]=r;
28         else {
29             while(r>i) {
30                 if(a[r]==a[i]) {r--;break;}
31                 vis[a[r--]]=false;
32             }
33             p[i]=r;
34         }
35     }
36     for(int i=1;i<=m&&t;++i) if(p[i]<m) t=false;
37 }
38 
39 inline bool check(int x) {
40     int l=0;
41     if(x) {
42         l=n-x;
43         if(p[1]<l) return false;
44     }
45     int r=l;
46     for(int i=l+1;i<=m;i+=n) {
47         r=min(m,r+n);
48         if(p[i]<r) return false;
49      }
50      return true;
51 }
52 
53 int hh() {
54     freopen("music.in","r",stdin);
55     freopen("music.out","w",stdout); 
56     read(n);read(m);
57     for(int i=1;i<=m;++i) read(a[i]);
58     
59     t=true,pre();
60     for(int i=0;i<n;++i)
61       if(n-i>m) ans+=t;
62       else ans+=check(i);
63     
64     printf("%d\n",ans);
65     fclose(stdin);fclose(stdout); 
66     return 0;
67 }
68 
69 int sb=hh();
70 int main(int argc,char**argv) {;}
代码

 

posted @ 2017-10-11 15:30  拿叉插猹哈  阅读(142)  评论(0编辑  收藏  举报