A:幸运数字Ⅰ
定义一个数字为幸运数字当且仅当它的所有数位都是4或者7。
比如说,47、744、4都是幸运数字而5、17、467都不是。
现在,给定一个字符串s,请求出一个字符串,使得:
1、它所代表的整数是一个幸运数字;
2、它非空;
3、它作为s的子串(不是子序列)出现了最多的次数(不能为0次)。
请求出这个串(如果有多解,请输出字典序最小的那一个)。
输入描述:
串s(1 <= |s| <= 50)。s只包含数字字符,可以有前导零。
输出描述:
一个串表示答案。 无解输出-1。
输入
047
输出
4
代码如下:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<string>
using namespace std;
string str;
int main()
{
cin>>str;
int ans4=0,ans7=0;
for (int i=0;i<str.size();i++) {
if (str[i]=='4') ans4++;
if (str[i]=='7') ans7++;
}
if (ans4||ans7) {
if (ans4>=ans7) printf("%d\n",4);
else if (ans4<ans7) printf("%d\n",7);
}
else {
printf("%d\n",-1);
}
return 0;
}
B:幸运数字Ⅱ
定义一个数字为幸运数字当且仅当它的所有数位都是4或者7。
比如说,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)。
输出描述:
一个数字表示答案。
输入
2 7
输出
33
代码如下:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<string>
#include<vector>
#include<algorithm>
#define ll unsigned long long
using namespace std;
const ll inf=1e12;
vector<ll> vec;
void dfs(int len,ll sum)
{
if (sum>inf) return ;
vec.push_back(sum);
dfs(len+1,sum*10+4);
dfs(len+1,sum*10+7);
}
int main()
{
dfs(0,(ll) 0);
sort(vec.begin(),vec.end());
ll left,right;
cin>>left>>right;
ll ans=0;
for (int i=1;i<vec.size();i++) {
if (left>right) break;
if (vec[i]>=left) {
if (vec[i]<=right) {
ans+=(vec[i]-left+1)*vec[i];
left=vec[i]+1;
}
else {
ans+=(right-left+1)*vec[i];
left=right+1;
}
}
}
cout<<ans;
}
C:幸运数字Ⅲ
定义一个数字为幸运数字当且仅当它的所有数位都是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会变成什么样子。
输入描述:
第一行两个整数n,k表示d的长度和操作次数。 第二行一个数表示d。数据保证不存在前导零。 1 <= n <= 100,000 0 <= k <= 1000,000,000
输出描述:
一个数字表示答案。
输入
7 4 4727447
输出
4427477
题目分析:
感谢评论席里的大佬指出错误。
这题存在俩个循环:
1:当出现447时,如果第二个4的位置是偶数,那么会变成477,若k不为0,那么接着又会变成447
2: 当出现477时,如果第一个4的位置是奇数,那么会变成447,若k不为0,那么接着又会变成477
如果出现这样的循环就需要根据当前k的值直接输出结果了
代码如下:
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+100;
char str[maxn];
int main()
{
int n,k;
scanf("%d%d",&n,&k);
scanf("%s",str+1);
for (int i=1;i<=n-1;i++) {
if (k==0) break;
if (str[i]=='4'&&str[i+1]=='7') {
if (i%2==0) {
if (i!=1&&str[i-1]=='4') {//447的情况
if (k%2==1) {
str[i]=str[i+1]='7';
printf("%s\n",str+1);
return 0;
}
else {
printf("%s\n",str+1);
return 0;
}
}
else {
k--;
str[i]=str[i+1]='7';
}
}
else {
if (i<=n-2&&str[i+2]=='7') {//477的情况
if (k%2==1) {
str[i]=str[i+1]='4';
printf("%s\n",str+1);
return 0;
}
else {
printf("%s\n",str+1);
return 0;
}
}
else {
k--;
str[i]=str[i+1]='4';
}
}
}
}
printf("%s\n",str+1);
return 0;
}
E:
乌龟跑步
有一只乌龟,初始在0的位置向右跑。
这只乌龟会依次接到一串指令,指令T表示向后转,指令F表示向前移动一个单位。乌龟不能忽视任何指令。
现在我们要修改其中正好n个指令(一个指令可以被改多次,一次修改定义为把某一个T变成F或把某一个F变成T)。
求这只乌龟在结束的时候离起点的最远距离。(假设乌龟最后的位置为x,我们想要abs(x)最大,输出最大的abs(x)
输入描述:
第一行一个字符串c表示指令串。c只由F和T构成。 第二行一个整数n。 1 <= |c| <= 100, 1 <= n <= 50
输出描述:
一个数字表示答案。
输入
FT 1
输出
2
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
int dp[110][55][220][2];
char str[110];
int main()
{
scanf("%s",str+1);
int n=strlen(str+1);
int m;
scanf("%d",&m);
memset (dp,0,sizeof (dp));
dp[0][0][100][1]=1;//假定位置在100
for (int i=1;i<=n;i++) {
for (int j=0;j<=m;j++) {
for (int k=0;k<=200;k++) {
if (str[i]=='F') {
if (j) dp[i][j][k][1]|=dp[i-1][j-1][k][0];//F变T 转向
if (j) dp[i][j][k][0]|=dp[i-1][j-1][k][1];
dp[i][j][k+1][1]|=dp[i-1][j][k][1];//前进
dp[i][j][k-1][0]|=dp[i-1][j][k][0];//后退
if (j>=2) dp[i][j][k+1][1]|=dp[i-1][j-2][k][1];//反转俩次不变,然后前进
if (j>=2) dp[i][j][k-1][0]|=dp[i-1][j-2][k][0];//后退
}
else {//和前面的差不多
if (j) dp[i][j][k+1][1]|=dp[i-1][j-1][k][1];
if (j) dp[i][j][k-1][0]|=dp[i-1][j-1][k][0];
dp[i][j][k][1]|=dp[i-1][j][k][0];
dp[i][j][k][0]|=dp[i-1][j][k][1];
if (j>=2) dp[i][j][k][1]|=dp[i-1][j-2][k][0];
if (j>=2) dp[i][j][k][0]|=dp[i-1][j-2][k][1];
}
}
}
}
int ans=0;
for (int i=0;i<=200;i++) {
if (dp[n][m][i][1]) ans=max(ans,(int) abs(100-i));
if (dp[n][m][i][0]) ans=max(ans,(int) abs(100-i));
}
printf("%d\n",ans);
}
F:
m皇后 在一个n*n的国际象棋棋盘上有m个皇后。
一个皇后可以攻击其他八个方向的皇后(上、下、左、右、左上、右上、左下、右下)。
对于某个皇后,如果某一个方向上有其他皇后,那么这个方向对她就是不安全的。
对于每个皇后,我们都能知道她在几个方向上是不安全的。
现在我们想要求出t 0,t 1,...,t 8,其中t i表示恰有i个方向是"不安全的"的皇后有多少
输入描述:
第一行两个整数n,m表示棋盘大小和皇后数量。 接下来m行每行两个整数ri,ci表示皇后坐标。 1 <= n, m <= 100,000 1 <= ri, ci <= n 数据保证没有皇后在同一个位置上。
输出描述:
一行九个整数表示答案。 空格隔开,结尾无空格
输入
8 4 4 3 4 8 6 5 1 6
输出
0 3 0 1 0 0 0 0 0
题目分析:图存不下,只能存点,搜索的话时间不允许,我们把八个方向分成4种
向上 向下 我把坐标按照横坐标相同,把纵坐标小的放在前面,否则吧横坐标小的放在前面
向左向右 我把坐标按照纵坐标相同,把横坐标小的放在前面,否则吧纵坐标小的放在前面
左上 右下 我们把纵坐标和横坐标相加的值排序,相同把横坐标小的放在前面
左下 右上 我们把横坐标和纵坐标相减的值排序,相同的横坐标小的放在前面
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct Dian
{
int a,b,id;
}dian[100005];
int num[100005],ans[9];
bool cmp1(const Dian &aa,const Dian &bb)
{
if(aa.b!=bb.b)return aa.b<bb.b;
return aa.a<bb.a;
}
bool cmp2(const Dian &aa,const Dian &bb)
{
if(aa.a!=bb.a)return aa.a<bb.a;
return aa.b<bb.b;
}
bool cmp3(const Dian &aa,const Dian &bb)
{
if(aa.a+aa.b!=bb.a+bb.b)return aa.a+aa.b<bb.a+bb.b;
return aa.a<bb.a;
}
bool cmp4(const Dian &aa,const Dian &bb)
{
if(aa.a-aa.b!=bb.a-bb.b)return aa.a-aa.b<bb.a-bb.b;
return aa.a<bb.a;
}
int main()
{
int n,m;
scanf("%d%d",&m,&n);
for(int i=1;i<=n;i++)
{
scanf("%d%d",&dian[i].a,&dian[i].b);
dian[i].id=i;
}
sort(dian+1,dian+1+n,cmp1);
for(int i=1;i<n;i++)
if(dian[i+1].b==dian[i].b)num[dian[i].id]++;
for(int i=n;i>1;i--)
if(dian[i-1].b==dian[i].b)num[dian[i].id]++;
sort(dian+1,dian+1+n,cmp2);
for(int i=1;i<n;i++)
if(dian[i+1].a==dian[i].a)num[dian[i].id]++;
for(int i=n;i>1;i--)
if(dian[i-1].a==dian[i].a)num[dian[i].id]++;
sort(dian+1,dian+1+n,cmp3);
for(int i=1;i<n;i++)
if(dian[i+1].a+dian[i+1].b==dian[i].a+dian[i].b)num[dian[i].id]++;
for(int i=n;i>1;i--)
if(dian[i-1].a+dian[i-1].b==dian[i].a+dian[i].b)num[dian[i].id]++;
sort(dian+1,dian+1+n,cmp4);
for(int i=1;i<n;i++)
if(dian[i+1].a-dian[i+1].b==dian[i].a-dian[i].b)num[dian[i].id]++;
for(int i=n;i>1;i--)
if(dian[i-1].a-dian[i-1].b==dian[i].a-dian[i].b)num[dian[i].id]++;
for(int i=1;i<=n;i++)
ans[num[i]]++;
for(int i=0;i<=8;i++)
{
printf("%d%c",ans[i],i==8?'\n':' ');
}
return 0;
}
D题好像是什么康托展开什么的,不会!
俩个大佬博客分享大家.