2020/12/14
A - Lucky Ticket
题意:幸运数字是只含幸运数字4和7的正整数。如果车票的号码是一个幸运数字,并且前半部分数字的和(前n/2位数字的和)等于后半部分数字的和(后n/2位数字的和),则称该车票为幸运车票,给一个长度为n的车票号码,判断所给的车票是否幸运。
题解:因为数字可能包含前导零,用字符串表示这个车票号码。遍历字符串,计算前n/2个数字的和与后n/2个数字的和,如果字符中有不是4或7的标记一下,直接输出NO,如果字符串只包含幸运数字,且前n/2个数字的和与后n/2个数字的和相等,输出YES.

#include<algorithm> #include<iostream> #include<cstdio> #include<cmath> using namespace std; int main(){ int n; int flag=0,sum1=0,sum2=0; string s; cin>>n>>s; for(int i=0;i<n;i++){ if(!(s[i]=='4'||s[i]=='7')){ flag=1; break; } if(i<n/2){ sum1+=s[i]-'0'; }else{ sum2+=s[i]-'0'; } } if(flag){ cout<<"NO"<<endl; }else if(!flag&&sum1==sum2){ cout<<"YES"<<endl; }else{ cout<<"NO"<<endl; } return 0; }
B - Lucky Mask
题意:幸运数字是只含幸运数字4和7的正整数。定义一个数的Mask是将这个数中幸运数字从左到右依次写入后得到的数字。例如例如72174994的MASK是7744。给任意整数a和幸运数字b,最小数字c (c>a),使数字c的MASK等于b。

#include<algorithm> #include<iostream> #include<cstring> #include<string> #include<cstdio> #include<cmath> using namespace std; int mask(int x){ string s; int ans=0; while(x){ if(x%10==4||x%10==7){ s+=x%10+'0'; } x=x/10; } for(int i=s.length()-1;i>=0;i--){ ans=ans*10+(s[i]-'0'); } return ans; } int main(){ int a,b; cin>>a>>b; int c=a+1; while(mask(c)!=b){ c++; } cout<<c<<endl; return 0; }

//看了一个别人写的,向他学习一下 #include<algorithm> #include<iostream> #include<cstring> #include<cstdio> #include<cmath> #include<string> using namespace std; typedef long long ll; #define MAXX 100010 string mask(int a){ string s; while(a){ if(a%10==4||a%10==7){ s+=a%10+'0'; } a=a/10; } reverse(s.begin(),s.end()); return s; } int main(){ int a; string b; int c; cin>>a>>b; c=a+1; while(b!=mask(c)){ c++; } cout<<c<<endl; return 0; }
C - Lucky Conversion
题意:给字符串a,b,a,b都是由幸运数字4和7构成的。a可以进行两种操作:1.交换任意两个位置的数 2.将4变成7或者将7变成4,求把a变成b的最小操作数
题解:执行操作1执行一次可以改变两个位置的数,所以尽可能地执行操作1,不能执行操作1的再执行操作2。统计有多少个位置a中是4 b中是7和a中是7b中是4,较小的数就是执行操作1的次数,两数的差值就是执行操作2的次数。

#include<algorithm> #include<iostream> #include<cstring> #include<cstdio> #include<cmath> #include<string> using namespace std; typedef long long ll; int main(){ ll sum=0,sum1=0,sum2=0; string a,b; char temp; cin>>a>>b; for(int i=0;i<a.length();i++){ if(a[i]=='7'&&b[i]=='4'){ sum1++; } if(a[i]=='4'&&b[i]=='7'){ sum2++; } } sum=min(sum1,sum2)+abs(sum1-sum2); cout<<sum<<endl; return 0; }
D - Lucky Number 2
题意:幸运数字是只含幸运数字4和7的正整数。设cnt(x)是数字d中数字x作为子串出现的次数,如果d = 747747,那么cnt(4) = 2, cnt(7) = 4, cnt(47) = 2, cnt(74) = 2。求一个幸运数字同时满足下列条件:cnt(4) = a1, cnt(7) = a2, cnt(47) = a3, cnt(74) = a4。如果没有数字满足输出-1
并且1 ≤ a1, a2, a3, a4 ≤ 106
题解:可以发现如果以4开头以7结尾,那么47一定比74多1;如果以7开头以4结尾,那么74一定比47多1;如果开头结尾都是4或都是7,那么47一定等于74。可以判断出当abs(47-74)>1时,一定是输出-1的。
1. 当cnt(47)>cnt(74),即a3>a4时,一定是444...447...4747477...7777;则此幸运数输出序列为a1-a3个4,a3个47,a2-a3个7,如果a1-a3<0或者a2-a3<0,输出-1
2. 当cnt(47)<cnt(74),即a3<a4时,一定是777...774...7474744...4444;则此幸运数输出序列为a2-a4个7,a4个74,a1-a4个4,如果a2-a4<0或者a1-a4<0,输出-1
3. 当cnt(47)=cnt(74),即a3=a4时
1)如果a1<=1且a2<=1,输出-1;因为如果a3>=1,a4>=1,至少有一个7两个4或者一个4两个7
2)如果a1-1>= a3且a2>=a3,一定是444...44747...474777...7774,则此幸运数输出序列为a1-a3-1个4,a3个47,a2-a3个7,一个4
3)如果a2-1>=a3且a1>=a3,一定是74747....474777....777,则此幸运数输出序列为一个7,a3个47,a2-a3-1个7

#include<cmath> #include<cstdio> #include<string> #include<cstring> #include<iostream> #include<algorithm> using namespace std; int main(){ int a1,a2,a3,a4; cin>>a1>>a2>>a3>>a4; if(abs(a3-a4)>1){ cout<<"-1"<<endl; return 0; }else if(a3>a4){ a1=a1-a3; a2=a2-a3; if(a1<0||a2<0){ cout<<"-1"<<endl; return 0; } while(a1--) cout<<"4"; while(a3--) cout<<"47"; while(a2--) cout<<"7"; cout<<endl; }else if(a3<a4){ a1=a1-a4; a2=a2-a4; if(a1<0||a2<0){ cout<<"-1"<<endl; return 0; } cout<<"7"; while(a1--) cout<<"4"; while(a3--) cout<<"47"; while(a2--) cout<<"7"; cout<<"4"<<endl; }else{ if(a1<=1&&a2<=1){ cout<<-1<<endl; return 0; } if(a1-1>=a3&&a2>=a3){ a1=a1-a3-1; a2=a2-a3; while(a1--) cout<<"4"; while(a3--) cout<<"47"; while(a2--) cout<<"7"; cout<<"4"<<endl; }else if(a2-1>=a3&&a1>=a3){ a2=a2-a3-1; cout<<"7"; while(a3--) cout<<"47"; while(a2--) cout<<"7"; cout<<endl; }else{ cout<<"-1"<<endl; } } }