2017-10-01-morning

T1 位运算1(bit)

Time Limit:1000ms   Memory Limit:128MB

题目描述

LYK拥有一个十进制的数N。它赋予了N一个新的意义:将N每一位都拆开来后再加起来就是N所拥有的价值。例如数字123拥有6的价值,数字999拥有27的价值。

假设数字N的价值是K,LYK想找到一个价值是K-1的数字,当然这个答案实在太多了,LYK想使得这个价值为K-1的数字尽可能大。

输入格式(bit.in)

    一个数N。

输出格式(bit.out)

一个数表示答案。你需要输出一个非负整数,且这个数不包含前导0。

输入样例1

199

输出样例1

198

输入样例2

1000

输出样例2

0

对于20%的数据n<=10

对于40%的数据n<=100

对于60%的数据n<=1000

对于100%的数据1<=n<=100000。

 1 /*
 2 把数的每一位拿出来,
 3 从最后判断是否可以减一 
 4 */
 5 #include <cstdio>
 6 
 7 inline void read(int &x)
 8 {
 9     x=0; register char ch=getchar();
10     for(; ch>'9'||ch<'0'; ) ch=getchar();
11     for(; ch>='0'&&ch<='9'; ch=getchar()) x=x*10+ch-'0';
12 }
13 int n,cnt,num[100005];
14 
15 int Presist()
16 {
17     freopen("bit.in","r",stdin);
18     freopen("bit.out","w",stdout);
19     read(n);
20     for(; n; n/=10) num[++cnt]=n%10;
21     for(int i=1; i<=cnt; ++i)
22         if(num[i]) { num[i]--; break; }
23     for(; cnt>1&&!num[cnt]; ) cnt--;
24     for(int i=cnt; i>=1; --i) printf("%d",num[i]);
25     return 0;
26 }
27 
28 int Aptal=Presist();
29 int main(int argc,char**argv){;}
AC

T2 火柴棒 (stick)

Time Limit:1000ms   Memory Limit:128MB

题目描述

众所周知的是,火柴棒可以拼成各种各样的数字。具体可以看下图:

    通过2根火柴棒可以拼出数字“1”,通过5根火柴棒可以拼出数字“2”,以此类推。

    现在LYK拥有k根火柴棒,它想将这k根火柴棒恰好用完,并且想知道能拼出的最小和最大的数分别是多少。

输入格式(stick.in)

    一个数k。

输出格式(stick.out)

    两个数,表示最小的数和最大的数。注意这两个数字不能有前导0。

输入样例

15

输出样例

108 7111111

数据范围

对于30%的数据k<=10。

对于60%的数据k<=20。

对于100%的数据1<k<=100。

  1 /*
  2 打表可以发现,最大值就只有1,7两种数字
  3 且容易发现k&1==1时,第一位是7,其余时1 
  4 最小值只有1,2,0,6,8这几种数字、
  5 且容易发现,出现8和6的情况可以特判 
  6 最多可能存在1个1或是2,其余是0或者8且0最多出现2个 
  7 */
  8 #include <cstring>
  9 #include <cstdio>
 10 
 11 inline void read(int &x)
 12 {
 13     x=0; register char ch=getchar();
 14     for(; ch>'9'||ch<'0'; ) ch=getchar();
 15     for(; ch>='0'&&ch<='9'; ch=getchar()) x=x*10+ch-'0';
 16 }
 17 const int use[10]={6,2,5,5,4,5,6,3,7,6};
 18 int k,num[55],cnt,tmp[55];
 19 bool flag;
 20 
 21 inline void Get_min()
 22 {
 23     for(int i=0; i<=9; ++i)
 24      if(use[i]==k)
 25      {
 26          printf("%d ",i);
 27          return ;
 28      }
 29     if(k%7==0) 
 30     {
 31         for(int i=1; i<=k/7; ++i)
 32             printf("8");
 33         printf(" "); return ;
 34     }
 35     else if(k%7==6)
 36     {
 37         printf("6");
 38         for(int i=1; i<=k/7; ++i)
 39             printf("8");
 40         printf(" "); return ;
 41     }
 42     int tmp=k;
 43     tmp-=2;num[++cnt]=1;
 44     if(tmp%7==0)
 45     {
 46         for(; tmp; tmp-=7) num[++cnt]=8;
 47         for(int i=1; i<=cnt; ++i) printf("%d",num[i]);
 48         printf(" "); return ;
 49     }
 50     tmp-=6;num[++cnt]=0;
 51     if(tmp%7==0)
 52     {
 53         for(; tmp; tmp-=7) num[++cnt]=8;
 54         for(int i=1; i<=cnt; ++i) printf("%d",num[i]);
 55         printf(" "); return ;
 56     }
 57     tmp-=6;num[++cnt]=0;
 58     if(tmp%7==0)
 59     {
 60         for(; tmp; tmp-=7) num[++cnt]=8;
 61         for(int i=1; i<=cnt; ++i) printf("%d",num[i]);
 62         printf(" "); return ;
 63     }
 64     tmp=k;cnt=0;
 65     tmp-=5;num[++cnt]=2;
 66     if(tmp%7==0)
 67     {
 68         for(; tmp; tmp-=7) num[++cnt]=8;
 69         for(int i=1; i<=cnt; ++i) printf("%d",num[i]);
 70         printf(" "); return ;
 71     }
 72     tmp-=6;num[++cnt]=0;
 73     if(tmp%7==0)
 74     {
 75         for(; tmp; tmp-=7) num[++cnt]=8;
 76         for(int i=1; i<=cnt; ++i) printf("%d",num[i]);
 77         printf(" "); return ;
 78     }
 79     tmp-=6;num[++cnt]=0;
 80     if(tmp%7==0)
 81     {
 82         for(; tmp; tmp-=7) num[++cnt]=8;
 83         for(int i=1; i<=cnt; ++i) printf("%d",num[i]);
 84         printf(" "); return ;
 85     }
 86 }
 87 inline void Get_max(int k)
 88 {
 89     if(k&1) k-=3,printf("7");
 90     for(; k; k-=2) printf("1");
 91 }
 92 
 93 int Presist()
 94 {
 95     freopen("stick.in","r",stdin);
 96     freopen("stick.out","w",stdout);
 97     read(k);
 98     if(k!=10) Get_min();
 99     else printf("22 "); Get_max(k);
100     return 0;
101 }
102 
103 int Aptal=Presist();
104 int main(int argc,char**argv){;}
考场AC代码
 1 #include <cmath>
 2 #include <cstdio>
 3 #include <cstdlib>
 4 #include <iostream>
 5 #include <algorithm>
 6 #include <string>
 7 #include <cstring>
 8 #include <map>
 9 #include <vector>
10 #include <set>
11 using namespace std;
12 long long dp[105];
13 int f[15],n;
14 int main()
15 {
16     freopen("stick.in","r",stdin);
17     freopen("stick.out","w",stdout);
18     f[1]=2; f[2]=5; f[3]=5; f[4]=4; f[5]=5;
19     f[6]=6; f[7]=3; f[8]=7; f[9]=6; f[0]=6;
20     dp[2]=1; dp[3]=7; dp[4]=4; dp[5]=2; dp[6]=6;dp[7]=8;
21     for (int i=8; i<=100; i++)
22     {
23         dp[i]=dp[i-f[0]]*10;
24       for (int j=0; j<=9; j++)
25         if (dp[i-f[j]]!=0)
26         dp[i]=min(dp[i],dp[i-f[j]]*10+j);
27     }
28     cin>>n;
29     cout<<dp[n]<<' ';
30     if (n%2==1) {cout<<7; n-=3;}
31     while (n){cout<<1; n-=2;}
32     return 0;
33 }
std动归

T3 听音乐(music)

Time Limit:1000ms   Memory Limit:128MB

题目描述

LYK喜欢听音乐,总共有n首音乐,有m个时刻,每个时刻LYK会听其中一首音乐,第i个时刻会听第ai首音乐。它给自己定了一个规定,就是从听音乐开始,听的每连续n首音乐都是互不相同的。例如当n=3时,从听歌开始,123321就是一个合法的顺序(此时LYK听了两轮歌,分别是123和321,每一轮的歌都是互不相同的),而121323就是一个不合法的顺序(LYK也听了两轮歌,第一轮中121存在听了两次相同的歌)。我们现在只截取其中一个片段,也就是说并不知道LYK之前已经听了什么歌。因此121323也仍然可以是一个合法的顺序,因为LYK之前可能听过3,然后再听121323,此时LYK听了三轮歌,分别是312,132和3。

现在LYK将告诉你这m个时刻它听的是哪首歌。你需要求出LYK在听这m首歌之前可能听过的歌的不同方案总数(我们认为方案不同当且仅当之前听过的歌的数量不同)。LYK向你保证它之前听过的歌的数量是在0~n-1之间的。因此你输出的答案也应当是0~n中的某个整数(答案是0表示LYK记错了,没有一个合法的方案)。

输入格式(music.in)

    第一行两个数n,m。

    第二行m个数表示ai。

输出格式(music.out)

    一个数表示答案。

输入样例1

4 10

3 4 4 1 3 2 1 2 3 4

输出样例1

1

样例解释1:LYK之前一定只听过2首歌(12或者21),这样可以分成3部分分别是34,4132,1234,每一部分都没有出现相同的歌。对于其它情况均不满足条件。

输入样例2

6 6

6 5 4 3 2 1

输出样例2

6

样例解释2:LYK之前听过0~5首歌的任意几首都是有可能满足条件的。

数据范围

对于50%的数据n,m<=1000。

对于100%的数据1<=n,m<=100000,1<=ai<=n。

其中均匀分布着n<m以及n>=m的情况。

提示:

LYK知道这个题目很长,但为了便于理解已经加了很多注释了……建议没看懂的同学们再重新看一遍……

 1 #include <cstdio>
 2 
 3 inline void read(int &x)
 4 {
 5     x=0; register char ch=getchar();
 6     for(; ch>'9'||ch<'0'; ) ch=getchar();
 7     for(; ch>='0'&&ch<='9'; ch=getchar()) x=x*10+ch-'0';
 8 }
 9 
10 const int N(100005);
11 int n,m,a[N],ans;
12 int stretch[N];
13 bool vis[N];
14 
15 inline void Prepare(int r)
16 {
17     stretch[r]=m;
18     vis[ a[r] ]=1;
19     for(int i=m-1; i; --i)
20     {
21         if(!vis[a[i]]) stretch[i]=r,vis[a[i]]=1;
22         else
23         {
24             for(; i<r; vis[a[r--]]=0 )
25               if(a[i]==a[r]){ r--; break; }
26             stretch[i]=r;
27         }
28     }
29 }
30 
31 int Presist()
32 {
33     freopen("music.in","r",stdin);
34     freopen("music.out","w",stdout);
35     read(n),read(m);
36     for(int i=1; i<=m; ++i) read(a[i]);
37     Prepare(m);    //处理出每个点作为歌单第一首所能得到的最长的歌单结束点 
38     if(n<m)        //此时能组成多个歌单 
39     {
40         for(int i=0,pos; i<=n; ++i)
41         {
42             if(stretch[1]<i) break;    //第一首无法匹配,就直接结束了 
43             for(int j=i+1; j<=m; j+=n)
44             {
45                 pos=m<(j+n-1)?m:(j+n-1);//找到结束点,判断是否匹配 
46                 if(stretch[j]<pos) goto lose;
47             }
48             ans++; lose:;
49         }
50     }
51     else    //至多两个 
52     {
53         for(int i=0; i<n; ++i)
54             if(i>=m) ans+=(stretch[1]==m);    // 判断能否得到一种歌单 
55             else ans+=(stretch[1]>=i&&stretch[i+1]>=m);//判断是否能得到分开的两个歌单 
56     }
57     printf("%d
",ans);
58     return 0;
59 }
60 
61 int Aptal=Presist();
62 int main(int argc,char**argv){;}
AC
——每当你想要放弃的时候,就想想是为了什么才一路坚持到现在。
原文地址:https://www.cnblogs.com/Shy-key/p/7645432.html