CODE FESTIVAL 2017 qual C
来源:互联网 发布:前10月经济数据 编辑:程序博客网 时间:2024/05/29 06:38
A
枚举
B
dp
C
因为可以添加x,所以我们可以忽略原串中的x,若剩下的串不回文则不合法,否则可以知道最终的回文串的中心是哪个字符,从两边向中间枚举非x的字符,添加x使他们的位置对应
code:
#include<set>#include<map>#include<deque>#include<queue>#include<stack>#include<cmath>#include<ctime>#include<bitset>#include<string>#include<vector>#include<cstdio>#include<cstdlib>#include<cstring>#include<climits>#include<complex>#include<iostream>#include<algorithm>#define ll long longusing namespace std;const int maxn = 410000;int n,m;char str[maxn];char s[maxn];int pos[maxn];int main(){ scanf("%s",str); n=strlen(str); m=0; for(int i=0;i<n;i++) if(str[i]!='x') pos[m]=i,s[m++]=str[i]; if(!m) return puts("0"),0; for(int i=0;i<m;i++) if(s[i]!=s[m-i-1]) return puts("-1"),0; int ans=0; int lai=0,laj=n-1,j=m-1; for(int i=0;i<=j;i++,j--) { int x=pos[i]-lai,y=laj-pos[j]; if(x!=y) ans+=abs(x-y); lai=pos[i],laj=pos[j]; } printf("%d\n",ans); return 0;}
D
f[i]表示前i个字符,最少要分成多少段,f[j]能转移到f[i]只有当j+1~i里面每种字符至多只能有一种出现奇数次,令g[i]二进制下第k位表示1~i k字母出现次数的奇偶性,则g[j]=g[i]或者g[j]和g[i]二进制只有一位不同
写个哈希表维护相同g[j]的最小值,枚举第0~26位与g[i]不同的g[j]更新f[i]
code:
#include<set>#include<map>#include<deque>#include<queue>#include<stack>#include<cmath>#include<ctime>#include<bitset>#include<string>#include<vector>#include<cstdio>#include<cstdlib>#include<cstring>#include<climits>#include<complex>#include<iostream>#include<algorithm>#define ll long long#define inf 1e9using namespace std;inline void down(int &x,const int &y){if(x>y)x=y;}const int maxn = 410000;const int mod = 2333333;int n;char str[maxn];int f[maxn];struct edge{int y,c,nex;}a[mod]; int len,fir[mod];inline void link(const int x,const int y,const int c){a[++len]=(edge){y,c,fir[x]};fir[x]=len;}void ins(const int x,const int ff){ int cc=x%mod; for(int k=fir[cc],y=a[k].y;k;k=a[k].nex,y=a[k].y) { if(a[k].y==x) { down(a[k].c,ff); return; } } link(cc,x,ff);}int fi(const int x){ int cc=x%mod; for(int k=fir[cc],y=a[k].y;k;k=a[k].nex) if(a[k].y==x) return a[k].c; return inf;}int main(){ scanf("%s",str+1); n=strlen(str+1); f[0]=1; ins(0,0); int now=0; for(int i=1;i<=n;i++) { f[i]=inf; now^=1<<str[i]-'a'; int mn=n+1; for(int j=0;j<26;j++) down(mn,fi(now^1<<j)); down(mn,fi(now)); f[i]=mn+1; ins(now,f[i]); } printf("%d\n",f[n]); return 0;}
E
没看懂啊啊啊啊
所以不想做跳了..
F
发现我们只需要考虑C吃的寿司,对于A,B第i次吃的寿司,只要求在c中的位置在c第i次吃的寿司之后,这个对于所有C吃的寿司序列,系数都是一样的,可以求出C吃的序列数后再做个dp求出这个系数。
求合法的C吃的寿司序列数,dp时C吃的什么先不确定,记作?,f[i][j][k]表示A吃到序列的第i个位置,B吃到j,C有k个?
转移时,如果当前的i,j不合法,转移到i+1或j+1,注意a[i]=b[j]的情况要特判,此时A,B都吃到了a[i]这个数,C中的?一定有一个是a[i],否则A,B就会有fight,所以转移到i+1,j+1,k-1带系数k
若i,j合法,有4种情况,
(1:?中没有a[i]和b[j],转移到i+1,j+1,k+1,
(2:?中有a[i]即C之前已经吃了a[i],转移到i+1,j,k-1带系数k,
(3:?中有b[j],同理到i,j+1,k-1带系数k,
(4:?中同时有a[i]和b[j],这种情况会被2,3各算一次,所以这种情况会转移到i+1,j+1,k-2带系数-k*(k-1)(去重)
算出C的序列数后再dp g[i][j]表示前i个位置放了j个不是C吃的数
code:
#include<set>#include<map>#include<deque>#include<queue>#include<stack>#include<cmath>#include<ctime>#include<bitset>#include<string>#include<vector>#include<cstdio>#include<cstdlib>#include<cstring>#include<climits>#include<complex>#include<iostream>#include<algorithm>#define ll long long#define __ %=Modusing namespace std;const int maxn = 405;const ll Mod = 1e9+7;int n,N;int a[maxn],b[maxn];ll f[maxn][maxn][200];int as[maxn],bs[maxn];ll g[maxn][maxn];int main(){ scanf("%d",&n); N=n/3; for(int i=1;i<=n;i++) scanf("%d",&a[i]),as[a[i]]=i; for(int i=1;i<=n;i++) scanf("%d",&b[i]),bs[b[i]]=i; //if(a[1]==b[1]) return puts("0"),0; f[1][1][0]=1ll; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) for(int k=0;k<=N;k++) if(f[i][j][k]) { ll tmp=f[i][j][k]; if(bs[a[i]]<=j||as[b[j]]<=i) { if(a[i]==b[j]) { if(k) (f[i+1][j+1][k-1]+=tmp*(ll)k%Mod)__; continue; } if(bs[a[i]]<=j) (f[i+1][j][k]+=tmp)__; else (f[i][j+1][k]+=tmp)__; continue; } (f[i+1][j+1][k+1]+=tmp)__; if(!k) continue; (f[i+1][j][k-1]+=tmp*(ll)k%Mod)__; (f[i][j+1][k-1]+=tmp*(ll)k%Mod)__; (f[i+1][j+1][k-2]-=tmp*(ll)k%Mod*(k-1)%Mod)__; } ll re=0; for(int i=N+1;i<=n+1;i++) (re+=f[i][n+1][0]+f[n+1][i][0])__; (re-=f[n+1][n+1][0]-Mod)%=Mod; g[0][0]=1ll; for(int i=0;i<n;i++) for(int j=0;j<=i;j++) if(g[i][j]) { if(i-j<N) (g[i+1][j]+=g[i][j])__; if(j<2*N&&(i-j)*2>j) (g[i+1][j+1]+=g[i][j]*(ll)((i-j)*2-j)%Mod)__; } (re*=g[n][2*N])__; printf("%lld\n",re); return 0;}
- CODE FESTIVAL 2017 qual C
- CODE FESTIVAL 2017 qual C C
- CODE FESTIVAL 2017 qual A C
- Atcoder CODE FESTIVAL 2017 qual C D
- [Atcoder CODE FESTIVAL 2017 qual C]D
- 【AtCoder CODE FESTIVAL 2017 qual C】D
- CODE FESTIVAL 2017 qual B:C
- CODE FESTIVAL 2017 qual B
- CODE FESTIVAL 2017 qual B
- CODE FESTIVAL 2017 qual A
- CODE FESTIVAL 2017 qual C- A-B-C 总结
- Atcoder CODE FESTIVAL 2017 qual C 总结+ABCD题解
- 【二分图染色】AtCoder CODE FESTIVAL 2017(qual B)C[3 Steps]题解
- AGC CODE FESTIVAL 2017 qual A(部分题解)
- Atcoder Code Festival 2016 Qual A D
- atcoder CODE FESTIVAL 2017 qual A 手速(雾)赛
- [待补完]CODE FESTIVAL 2017 Final (Parallel) A,B,C(搜索)
- Code Festival 2017 qualA E-Modern Painting
- 【BigHereo 29】---T8-《信息系统开发与管理》---系统维护和评价
- 前端高性能计算之一:WebWorkers
- 10.24离线赛总结
- 谈谈码率、帧率、分辨率和清晰度
- mybatis字符串匹配数字
- CODE FESTIVAL 2017 qual C
- 台大-林轩田老师-机器学习基石学习笔记2
- android 判断某个字符串包含某个字符串的个数
- 在jsp中进行文件的读写操作
- 熊猫学猿--第六竹(函数)
- 普元 EOS Platform 7.6 Oracle数据库,定时任务偶尔出现不执行问题
- Java面试题集锦
- XRecyclerView 上拉加载 下拉刷新
- window下编程的编码小坑