链接:https://www.nowcoder.com/acm/contest/70/A
来源:牛客网
幸运数字Ⅰ
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
题目描述
定义一个数字为幸运数字当且仅当它的所有数位都是4或者7。
比如说,47、744、4都是幸运数字而5、17、467都不是。
现在,给定一个字符串s,请求出一个字符串,使得:
1、它所代表的整数是一个幸运数字;
2、它非空;
3、它作为s的子串(不是子序列)出现了最多的次数(不能为0次)。
请求出这个串(如果有多解,请输出字典序最小的那一个)。
比如说,47、744、4都是幸运数字而5、17、467都不是。
现在,给定一个字符串s,请求出一个字符串,使得:
1、它所代表的整数是一个幸运数字;
2、它非空;
3、它作为s的子串(不是子序列)出现了最多的次数(不能为0次)。
请求出这个串(如果有多解,请输出字典序最小的那一个)。
输入描述:
串s(1 <= |s| <= 50)。s只包含数字字符,可以有前导零。
输出描述:
一个串表示答案。
无解输出-1。
示例1
输入
047
输出
4
示例2
输入
16
输出
-1
虽然是找子序列,但是你想啊,要出现次数最多,那么一定是4和7
所以答案就只有4和7,分情况讨论下
#includeusing namespace std; string str; int main() { ios::sync_with_stdio(false); cin>>str; int sum1=0,sum2=0; for(int i=0;str[i];i++) { if(str[i]=='4') sum1++; if(str[i]=='7') sum2++; } if(sum1==0&&sum2==0) { cout<<-1; return 0; } if(sum1==sum2) cout<<4; else if(sum1>sum2) cout<<4; else cout<<7; return 0; }
可以写短点的啊
#includeusing namespace std; string s; int a[256]; int main() { ios::sync_with_stdio(false); cin>>s; for(int i=0;s[i];i++)a[s[i]]++; if(!a['4']&&!a['7']) cout<<-1; else if(a['4']>=a['7']) cout<<4; else cout<<7; return 0; }
链接:https://www.nowcoder.com/acm/contest/70/B
来源:牛客网
幸运数字Ⅱ
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
题目描述
定义一个数字为幸运数字当且仅当它的所有数位都是4或者7。
比如说,47、744、4都是幸运数字而5、17、467都不是。
定义next(x)为大于等于x的第一个幸运数字。给定l,r,请求出next(l) + next(l + 1) + ... + next(r - 1) + next(r)。
比如说,47、744、4都是幸运数字而5、17、467都不是。
定义next(x)为大于等于x的第一个幸运数字。给定l,r,请求出next(l) + next(l + 1) + ... + next(r - 1) + next(r)。
输入描述:
两个整数l和r (1 <= l <= r <= 1000,000,000)。
输出描述:
一个数字表示答案。
示例1
输入
2 7
输出
33
示例2
输入
7 7
输出
7
BFS生成这个序列,然后去统计每个区段是多少个
#includeusing namespace std; typedef long long ll; const int N=1e5+5; ll luck[N]; int cnt,a[2]={4,7}; struct T { ll x,step; } first,cur,nxt; void bfs() { queue q; first={0,0}; q.push(first); while(!q.empty()) { cur=q.front(); q.pop(); if(cur.step>9) { return; } for(int i=0; i<2; i++) { nxt.x=cur.x*10+a[i]; nxt.step=cur.step+1; q.push(nxt); luck[++cnt]=nxt.x; } } } int main() { bfs(); ll l,r; cin>>l>>r; ll tmp1,tmp2; tmp1=-1; ll sum=0; for(int i=0;i<10000;i++) { if(luck[i]>=l&&tmp1==-1) { tmp1=i; } if(luck[i]>=r) { tmp2=i; break; } } for(int i=tmp1;i<=tmp2;i++) { sum+=(min(luck[i],r)-l+1)*luck[i]; l=luck[i]+1; } cout<<sum; return 0; }
下面的循环还可以这样缩短,其实相当于用0 1去模拟4和7,bfs出序列就不用排序,dfs的需要sort一下
#includeusing namespace std; typedef long long ll; const int N=1e5+5; ll a[N]; int cnt,b[2]={4,7}; struct T { ll x,step; } first,cur,nxt; void bfs() { queue q; first={0,0}; q.push(first); while(!q.empty()) { cur=q.front(); q.pop(); if(cur.step>9)return; for(int i=0; i<2; i++) nxt.x=cur.x*10+b[i],nxt.step=cur.step+1,q.push(nxt),a[++cnt]=nxt.x; } } int main() { bfs(); ll l,r; cin>>l>>r; ll sum=0,now=l,pos=0; while(now<=r) { while(a[pos] pos; sum+=a[pos]*(min(r,a[pos])-now+1); now=a[pos]+1; } cout<<sum; return 0; }
链接:https://www.nowcoder.com/acm/contest/70/C
来源:牛客网
幸运数字Ⅲ
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
题目描述
定义一个数字为幸运数字当且仅当它的所有数位都是4或者7。
比如说,47、744、4都是幸运数字而5、17、467都不是。
假设现在有一个数字d,现在想在d上重复k次操作。
假设d有n位,用d 1,d 2,...,d n表示。
对于每次操作,我们想要找到最小的x (x < n),使得d x=4并且d x+1=7。
如果x为奇数,那么我们把d x和d x+1都变成4;
否则,如果x为偶数,我们把d x和d x+1都变成7;
如果不存在x,那么我们不做任何修改。
现在请问k次操作以后,d会变成什么样子。
比如说,47、744、4都是幸运数字而5、17、467都不是。
假设现在有一个数字d,现在想在d上重复k次操作。
假设d有n位,用d 1,d 2,...,d n表示。
对于每次操作,我们想要找到最小的x (x < n),使得d x=4并且d x+1=7。
如果x为奇数,那么我们把d x和d x+1都变成4;
否则,如果x为偶数,我们把d x和d x+1都变成7;
如果不存在x,那么我们不做任何修改。
现在请问k次操作以后,d会变成什么样子。
输入描述:
第一行两个整数n,k表示d的长度和操作次数。
第二行一个数表示d。数据保证不存在前导零。
1 <= n <= 100,000
0 <= k <= 1000,000,000
输出描述:
一个数字表示答案。
示例1
输入
7 4 4727447
输出
4427477
示例2
输入
4 2 4478
输出
4478
有特殊的数字,447和477会循环,其他的也不会回退,枚举这两个就可以了
#includeusing namespace std; typedef long long ll; string s; int main() { int n,k; cin>>n>>k>>s; for(int i=1; s[i]&&k; i++) { if(s[i-1]=='4'&&s[i]=='7') { if(i-1!=0&&s[i-2]=='4'&&i%2==0) { if(k&1)s[i-1]='7'; k=0; } else if(s[i+1]=='7'&&i%2==1) { if(k&1)s[i]='4'; k=0; } else { k--; if(i&1)s[i]='4'; else s[i-1]='7'; } } } cout<<s; return 0; }
链接:https://www.nowcoder.com/acm/contest/70/F
来源:牛客网
m皇后
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
题目描述
在一个n*n的国际象棋棋盘上有m个皇后。
一个皇后可以攻击其他八个方向的皇后(上、下、左、右、左上、右上、左下、右下)。
对于某个皇后,如果某一个方向上有其他皇后,那么这个方向对她就是不安全的。
对于每个皇后,我们都能知道她在几个方向上是不安全的。
现在我们想要求出t 0,t 1,...,t 8,其中t i表示恰有i个方向是"不安全的"的皇后有多少个。
一个皇后可以攻击其他八个方向的皇后(上、下、左、右、左上、右上、左下、右下)。
对于某个皇后,如果某一个方向上有其他皇后,那么这个方向对她就是不安全的。
对于每个皇后,我们都能知道她在几个方向上是不安全的。
现在我们想要求出t 0,t 1,...,t 8,其中t i表示恰有i个方向是"不安全的"的皇后有多少个。
输入描述:
第一行两个整数n,m表示棋盘大小和皇后数量。i
接下来m行每行两个整数ri,ci表示皇后坐标。
1 <= n, m <= 100,000
1 <= r
, ci
<= n
数据保证没有皇后在同一个位置上。
输出描述:
一行九个整数表示答案。
空格隔开,结尾无空格
示例1
输入
8 4 4 3 4 8 6 5 1 6
输出
0 3 0 1 0 0 0 0 0
示例2
输入
10 3 1 1 1 2 1 3
输出
0 2 1 0 0 0 0 0 0
这也算模拟吧,找到每一行最左边的点最右边的点,每一列最上面的点,最下面的点,还有四个方向,然后判断这个点在他的什么方向,它是的话就有,不是的话就没有
#includeusing namespace std; vector int,int> > v; const int N=1e5+5,INF=1e9+7; int minnx[2*N]; int minny[2*N]; int minnd[2*N]; int minnb[2*N]; int maxxx[N]; int maxxy[N]; int maxxd[2*N]; int maxxb[2*N]; int s[10]; int main() { int n,m; scanf("%d%d",&n,&m); for(int i=1;i<2*N;i++) minnx[i]=INF,minny[i]=INF,minnd[i]=INF,minnb[i]=INF; for(int i=0,x,y;i ) { scanf("%d%d",&x,&y); v.push_back(make_pair(x,y)); minnx[x]=min(minnx[x],y); maxxx[x]=max(maxxx[x],y); minny[y]=min(minny[y],x); maxxy[y]=max(maxxy[y],x); minnd[N+y-x]=min(minnd[N+y-x],x); maxxd[N+y-x]=max(maxxd[N+y-x],x); minnb[x+y]=min(minnb[x+y],x); maxxb[x+y]=max(maxxb[x+y],x); } for(int i=0;i ) { int sum=0,nx=v[i].first,ny=v[i].second; if(nx>minny[ny]) sum++; if(nx<maxxy[ny]) sum++; if(ny>minnx[nx]) sum++; if(ny<maxxx[nx]) sum++; if(nx>minnd[N+ny-nx]) sum++; if(nx nx]) sum++; if(nx>minnb[nx+ny]) sum++; if(nx ny]) sum++; s[sum]++; } cout< 0]; for(int i=1;i<9;i++)cout<<" "<<s[i]; return 0; }