A. No to Palindromes!
题目链接
http://codeforces.com/contest/464/problem/A
题目大意
给你一个字符串
S
,其中不包含任何长度大于等于2的回文子串,要你找一个长度和
思路
显然
S′
的前缀是和
S
相同的,而二者的后缀则不同。假设二者不相同的后缀对应于区间
由于
S
本身已经保证不包含任何长度大于等于2的回文子串,因此,在S
代码
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#define MAXN 1100
using namespace std;
char s[MAXN],original[MAXN];
int n,p,num[MAXN];
char Find(int pos)
{
for(char ch=s[pos]+1;ch<='a'+p-1;ch++)
{
if((pos>=2&&ch==s[pos-1])||(pos>=3&&ch==s[pos-2])) continue;
else return ch;
}
return 0;
}
bool solve()
{
int L=-1;
for(int i=n;i>=1;i--)
{
char tmp=Find(i);
if(tmp)
{
s[i]=tmp;
L=i;
break;
}
}
if(L==-1) return false;
for(int i=L+1;i<=n;i++)
{
s[i]='a'-1;
char tmp=Find(i);
if(tmp) s[i]=tmp;
}
return true;
}
int main()
{
scanf("%d%d",&n,&p);
scanf("%s",s+1);
for(int i=1;i<=n;i++) original[i]=s[i];
if(!solve()) printf("NO\n");
else printf("%s",s+1);
return 0;
}
B. Restore Cube
题目链接
http://codeforces.com/contest/464/problem/B
题目大意
给你八个点的坐标 (xi,yi,zi) ,要你对这八个点的坐标的 x,y,z 重新排列,使得新的八个点构成一个立方体。输出一种方案,无解输出NO
思路
本次比赛最水的题,不过还是很卡细节的
直接DFS枚举八个点的排列情况即可。每次枚举完之后,进行八次判定。第
i
次判定固定点
代码
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#define MAXN 10
using namespace std;
typedef long long int LL;
struct Point
{
LL x,y,z;
Point(){}
Point(LL _x,LL _y,LL _z):x(_x),y(_y),z(_z){}
}points[10];
LL dist(Point a,Point b)
{
return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)+(a.z-b.z)*(a.z-b.z);
}
LL dis[10];
int top=0;
bool check(int p)
{
top=0;
for(int i=1;i<=8;i++)
if(i!=p) dis[++top]=dist(points[p],points[i]);
sort(dis+1,dis+top+1);
if(dis[1]==0) return false;
if(dis[1]!=dis[2]||dis[1]!=dis[3]) return false;
if(dis[4]!=dis[5]||dis[4]!=dis[6]) return false;
if(dis[1]*2!=dis[4]||dis[1]*3!=dis[7]) return false;
return true;
}
void DFS(int pos)
{
if(pos>8)
{
bool flag=true;
for(int i=1;i<=8;i++)
if(!check(i))
{
flag=false;
break;
}
if(flag)
{
printf("YES\n");
for(int i=1;i<=8;i++)
printf("%I64d %I64d %I64d\n",points[i].x,points[i].y,points[i].z);
exit(0);
}
return;
}
Point tmp=points[pos];
DFS(pos+1);
points[pos]=Point(tmp.x,tmp.z,tmp.y);
DFS(pos+1);
points[pos]=Point(tmp.y,tmp.x,tmp.z);
DFS(pos+1);
points[pos]=Point(tmp.y,tmp.z,tmp.x);
DFS(pos+1);
points[pos]=Point(tmp.z,tmp.x,tmp.y);
DFS(pos+1);
points[pos]=Point(tmp.z,tmp.y,tmp.x);
DFS(pos+1);
}
int main()
{
for(int i=1;i<=8;i++)
scanf("%I64d%I64d%I64d",&points[i].x,&points[i].y,&points[i].z);
DFS(1);
printf("NO\n");
return 0;
}
C. Substitutes in Number
题目链接
http://codeforces.com/contest/464/problem/C
题目大意
给你一个数字
S
,
思路
因为最后要输出的答案是要取模的,很容易想到这个题和数学、DP有关系。
如果正序来回答所有询问的话,每次取了模之后,之后的询问显然就做不了了,因此需要离线倒序解决询问。从
n
到1枚举第
若第
t
个询问是将数位
代码
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#include <string>
#define MOD 1000000007
#define MAXN 110000
using namespace std;
typedef long long int LL;
LL fastPow(LL base,LL pow)
{
LL ans=1;
while(pow)
{
if(pow&1) ans=ans*base%MOD;
base=base*base%MOD;
pow>>=1;
}
return ans;
}
LL pow[MAXN];
char s[MAXN],tmp[MAXN];
int n,q;
struct Operate
{
int x;
string s;
}opt[MAXN];
LL length[12]; //length[i]=经过了t~n号操作后,数字i变成的新数字的长度(用10^i mod p表示)
LL val[12]; //val[i]=经过了t~n号操作后,数字i变成的新数字的取模后的值
int main()
{
scanf("%s",s);
n=strlen(s);
scanf("%d",&q);
for(int i=1;i<=q;i++)
{
scanf("%d->",&opt[i].x);
gets(tmp);
opt[i].s=tmp;
}
for(int i=0;i<=9;i++)
{
val[i]=i;
length[i]=10;
}
for(int t=q;t>=1;t--)
{
LL len=opt[t].s.length();
if(!len)
{
val[opt[t].x]=0;
length[opt[t].x]=1;
continue;
}
LL now=0,nowlen=1; //now=t~q号操作后,数字opt[t].x变成的数字取模的值,nowlen=t~q号操作后,数字opt[t].x变成的数字长度(10^i mod p表示)
for(int i=0;i<len;i++)
{
now=now*length[opt[t].s[i]-'0']%MOD;
now=(now+val[opt[t].s[i]-'0'])%MOD;
nowlen=(nowlen*length[opt[t].s[i]-'0'])%MOD;
}
val[opt[t].x]=now;
length[opt[t].x]=nowlen;
}
int len=strlen(s);
LL now=0; //now=1~q号操作后,初始数字变成的数字取模的值
for(int i=0;i<len;i++)
{
now=now*length[s[i]-'0']%MOD;
now=(now+val[s[i]-'0'])%MOD;
}
printf("%I64d\n",now);
return 0;
}