Codeforces #265 Div 1 简要题解
2015-06-24 16:16
627 查看
A. No to Palindromes!
题目链接
http://codeforces.com/contest/464/problem/A题目大意
给你一个字符串SS,其中不包含任何长度大于等于2的回文子串,要你找一个长度和SS相同,且字典序比SS大的字典序最小的S′S',使得S′S'也不包含任何长度大于等于2的回文子串。思路
显然S′S'的前缀是和SS相同的,而二者的后缀则不同。假设二者不相同的后缀对应于区间[t,|S|][t,|S|]。我们首先要找出最大的tt,使得第tt位修改后,S′S'的[1,t][1,t]部分不含任何长度大于等于2的回文串。在确定下来tt之后,我们再向后把[t+1,|S|][t+1,|S|]这部分都确定下来。由于SS本身已经保证不包含任何长度大于等于2的回文子串,因此,在SSS上修改第xx位字符,只要保证第xx位字符不会构成新的长度为2或3的回文子串即可(也就是第xx位和第x−1,x−2,x+1,x+2x-1,x-2,x+1,x+2位不相同)。由于我们这里是从左往右确定S′S'的字符,因此在考虑第xx位时,第x+1,x+2...x+1,x+2...位还没确定下来,因此只要保证第xx位和第x−1,x−2x-1,x-2位不相同就行了
代码
#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_i,y_i,z_i),要你对这八个点的坐标的x,y,zx,y,z重新排列,使得新的八个点构成一个立方体。输出一种方案,无解输出NO思路
本次比赛最水的题,不过还是很卡细节的直接DFS枚举八个点的排列情况即可。每次枚举完之后,进行八次判定。第ii次判定固定点ii,求出点1,2...81,2...8到点ii的七个距离。若这八个点可以构成立方体,则其中三个距离为aa,另外有三个距离2√a\sqrt 2 a,另外还有一个距离3√a\sqrt 3 a
代码
#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题目大意
给你一个数字SS,qq次将其中的所有的数位t(0≤t≤9)t(0\leq t\leq 9)替换成一个数字(这个数字可能大于10),或者删去所有的这样的数位。问最终这个数字mod109+7\mod 10^9+7的值是多少思路
因为最后要输出的答案是要取模的,很容易想到这个题和数学、DP有关系。如果正序来回答所有询问的话,每次取了模之后,之后的询问显然就做不了了,因此需要离线倒序解决询问。从nn到1枚举第tt个询问,维护val[i]=val[i]=数位ii在t+1t+1到nn号操作后的取模的值,length[i]=length[i]=数位ii在t+1t+1到nn号操作后的数字长度(注:长度若是ll,则length[i]=10lmod109+7length[i]=10^l\mod 10^9+7)。
若第tt个询问是将数位xx变成了数字ss,我们可以很容易地用所有的val[i],length[i]val[i],length[i]代换出val[x]val[x]。最后我们再用所有的val[i],length[i]val[i],length[i]代换出SS的值即可
代码
#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; }
相关文章推荐
- 随机生成30个数字(范围0-30)存到一个数组中,将数组中重复的数字去除,动态创建数组保存剩下的数字
- Android WebView开发问题及优化汇总
- 项目搭建系列之三:SpringMVC框架下使用Ehcache对象、数据缓存
- Appium键盘操作
- Win10新设置的PIN码不能登录或删除和修改等操作
- 安卓用SharedPreference实现记住用户名和密码
- 聚焦SAT之散文写作素材整理
- 杨鹏:17天搞定gre单词的方法
- 如何处理qq for linux Dear user.your version of the software will be obsole
- Xcode
- 出行
- 使用CSS实现outline切换的动画效果
- js里面的等于号--
- java web中的多条件查询
- 汉诺塔算法
- html等比例缩放图片
- Android初学笔记——内部存储器的读写
- 关于RPC服务器不可用,导致电源设置无法更改的解决方法
- IOS 开发学习37 的Architecture与iphone版本对应关系
- MySQL启动多实例