链接: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,分情况讨论下
#include<bits/stdc++.h>
using 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;
}
可以写短点的啊
#include<bits/stdc++.h>
using 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生成这个序列,然后去统计每个区段是多少个
#include<bits/stdc++.h>
using 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<T>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一下
#include<bits/stdc++.h>
using 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<T>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]<now) ++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位,用d1,d2,...,dn表示。
对于每次操作,我们想要找到最小的x (x < n),使得dx=4并且dx+1=7。
如果x为奇数,那么我们把dx和dx+1都变成4;
否则,如果x为偶数,我们把dx和dx+1都变成7;
如果不存在x,那么我们不做任何修改。
现在请问k次操作以后,d会变成什么样子。
比如说,47、744、4都是幸运数字而5、17、467都不是。
假设现在有一个数字d,现在想在d上重复k次操作。
假设d有n位,用d1,d2,...,dn表示。
对于每次操作,我们想要找到最小的x (x < n),使得dx=4并且dx+1=7。
如果x为奇数,那么我们把dx和dx+1都变成4;
否则,如果x为偶数,我们把dx和dx+1都变成7;
如果不存在x,那么我们不做任何修改。
现在请问k次操作以后,d会变成什么样子。
输入描述:
第一行两个整数n,k表示d的长度和操作次数。第二行一个数表示d。数据保证不存在前导零。1 <= n <= 100,0000 <= k <= 1000,000,000
输出描述:
一个数字表示答案。
示例1
输入
7 4 4727447
输出
4427477
示例2
输入
4 2 4478
输出
4478
有特殊的数字,447和477会循环,其他的也不会回退,枚举这两个就可以了
#include<bits/stdc++.h>
using 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个皇后。
一个皇后可以攻击其他八个方向的皇后(上、下、左、右、左上、右上、左下、右下)。
对于某个皇后,如果某一个方向上有其他皇后,那么这个方向对她就是不安全的。
对于每个皇后,我们都能知道她在几个方向上是不安全的。
现在我们想要求出t0,t1,...,t8,其中ti表示恰有i个方向是"不安全的"的皇后有多少个。
一个皇后可以攻击其他八个方向的皇后(上、下、左、右、左上、右上、左下、右下)。
对于某个皇后,如果某一个方向上有其他皇后,那么这个方向对她就是不安全的。
对于每个皇后,我们都能知道她在几个方向上是不安全的。
现在我们想要求出t0,t1,...,t8,其中ti表示恰有i个方向是"不安全的"的皇后有多少个。
输入描述:
第一行两个整数n,m表示棋盘大小和皇后数量。接下来m行每行两个整数ri,ci表示皇后坐标。1 <= n, m <= 100,0001 <= ri
, 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
这也算模拟吧,找到每一行最左边的点最右边的点,每一列最上面的点,最下面的点,还有四个方向,然后判断这个点在他的什么方向,它是的话就有,不是的话就没有
#include<bits/stdc++.h>
using namespace std;
vector<pair<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<m;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<m;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<maxxd[N+ny-nx])
sum++;
if(nx>minnb[nx+ny])
sum++;
if(nx<maxxb[nx+ny])
sum++;
s[sum]++;
}
cout<<s[0];
for(int i=1;i<9;i++)cout<<" "<<s[i];
return 0;
}
来源:https://www.cnblogs.com/BobHuang/p/8587079.html