标签:比较 数字 flag 取绝对值 之间 一个 情况 cout ==
题目链接:https://codeforces.com/contest/1295/problem/A
A题~ 水题一枚~
题意:电子表上显示每个数字的屏幕由七块组成,(如图所示现在给你一个数字n,代表有n块可用的区域,问你可以显示的最大数字是多少?
题解:
如图,为显示数字0~9所需要的显示屏的数量。
用有限的显示屏显示最大的数字,那么就要保证 条件1.数字的位数最大(位数大数字一定大)条件2.相同位数的情况下,开头的数字尽可能大。
不难发现,显示数字1所需要的显示屏数量最少,所以尽可能的多显示数字1以满足条件1。
在满足上述条件的前提下,剩余的显示屏的数量必为1或0,如果剩下一个就把第一个数字1变成7即可,以满足条件2。
(实际上只会出现1和7两个数字
AC代码
1 #include<bits/stdc++.h> 2 using namespace std; 3 int main(){ 4 5 int t; 6 cin>>t; 7 8 while(t--){ 9 10 int n; 11 cin>>n; 12 13 int p=n%2; 14 n/=2; 15 16 for(int i=1;i<=p;i++){ 17 cout<<7; 18 } 19 20 for(int i=p+1;i<=n;i++){ 21 cout<<1; 22 } 23 cout<<endl; 24 25 } 26 27 return 0; 28 29 }
题目链接:https://codeforces.com/contest/1295/problem/B
B题~ Orz
题意:给出一个长度为n的只含01的字符串s,字符串t可以由任意多个s组成,即t=ssss....(最后一个s可以只取前面的一部分),字符串中的01带有权值,‘0‘计为+1,‘1‘计为-1,每一位对应的值为权值的前缀和。给出一个数字x,问使得权值等于x的t有几个(无限个则输出-1)?
题解:
一开始看到题目的时候很懵逼,感觉无从下手却又有迹可循?
感觉像是一个前缀和的题目?
实际上确实和前缀和有点关系。
字符串t是一个由无限个s组成的字符串,t的每一位也会有自己对应的权值(也有相应的前缀和),我们只需要找到在这个序列中,有几个位置的前缀和等于x即可。
对于样例1
字符串s:010010,对应的前缀和为101212,t对应的前缀和则为101212 323434 545656 ........... 9 8 9 10 9 10 11 10 11 12 11 12 ......... 不难发现有3个位置前缀和为10。
可以发现t中的前缀和有规律可循,即a[i]=a[i-n]+a[n],(i>n)。可以通过一个简单的递推式求出后续每项的前缀和。
但是,如果逐项推下去依次检索(即暴搜)必会TLE,就要想办法进行优化。
通过上述递推式,可以推出,如果某个位置的前缀和a[i]==x,(i>0)则会有对应的,a[j]+k*x==x(j>n)。
也就是说,只要检验从1~n项的前缀和a[j]加k*a[n]是否等于x,是否有满足条件的k(k必须>=0)存在,如果存在,则会有一个对应数字k使第(i+k*n)项前缀和等于x,如果不存在则后续所有的第(i+k*n)项都不满足。
如何检验呢?
这里我使用了一种比较神奇的方法(就是瞎搞搞推出来的,推理过程不赘述)——取模。
如果满足条件,x一定比a[j]多k个a[n],那么只要x和a[j]模a[n]的结果相同(即把x去掉k个a[n]),即成立。
但是这样取模会出现正负数之间取模、和模0的问题,所以,这里采用a[j]和x同号则绝对值相减(差也取绝对值以保证为正数)取模a[n]的绝对值,异号则绝对值相加取模a[n]的绝对值,如果结果为零则成立。同时要判断k>=0是否成立,如果a[j]>x且a[n]>0或者a[j]<x且a[n]<0,此时k<0,不成立。对有无限个解的情况进行特判,即a[n]==0且存在前缀和a[j]==x,直接输出-1,如果a[n]==0且不存在a[j]==x,那么无解输出0。
AC代码
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 long long a[100001]; 5 6 long long absj(long long a,long long b){ 7 return abs(abs(a)-abs(b)); 8 } 9 10 long long absp(long long a,long long b){ 11 return abs(abs(a)+abs(b)); 12 } 13 14 int main(){ 15 16 int t; 17 cin>>t; 18 19 while(t--){ 20 21 long long n,x; 22 cin>>n>>x; 23 24 string s; 25 cin>>s; 26 27 s=‘%‘+s; 28 29 a[0]=0; 30 bool flag=0; 31 32 for(int i=1;i<=n;i++){ 33 34 if(s[i]==‘1‘){ 35 a[i]=a[i-1]-1; 36 } 37 else{ 38 a[i]=a[i-1]+1; 39 } 40 41 if(x==a[i]){ 42 flag=1; 43 } 44 45 } 46 47 if(a[n]==0){ 48 if(flag==1) cout<<-1<<endl; 49 else cout<<0<<endl; 50 continue; 51 } 52 53 long long ans=0; 54 55 if(x==0){ 56 ans++; 57 } 58 59 for(int i=1;i<=n;i++){ 60 61 if((a[i]>x&&a[n]>0)||(a[i]<x&&a[n]<0)){ 62 continue; 63 } 64 65 if(a[i]*x>=0&&absj(a[i],x)%abs(a[n])==0){ 66 ans++; 67 } 68 if(a[i]*x<0&&absp(a[i],x)%abs(a[n])==0){ 69 ans++; 70 } 71 72 } 73 74 cout<<ans<<endl; 75 76 } 77 78 return 0; 79 80 }
(Orz,在线投诉老学姐压榨学弟写题!!!!)
摸过的??,划过的水,早晚要还的~(暗示ljxfp赶紧来写题)
Educational Codeforces Round 81 (Rated for Div. 2)
标签:比较 数字 flag 取绝对值 之间 一个 情况 cout ==
原文地址:https://www.cnblogs.com/VioletOrz/p/12244500.html