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){;}
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){;}
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 }
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\n",ans); 58 return 0; 59 } 60 61 int Aptal=Presist(); 62 int main(int argc,char**argv){;}