博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
XVIII Open Cup named after E.V. Pankratiev. Grand Prix of Peterhof
阅读量:4608 次
发布时间:2019-06-09

本文共 9701 字,大约阅读时间需要 32 分钟。

A. City Wall

找规律。

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;void fre() { }#define MS(x, y) memset(x, y, sizeof(x))#define ls o<<1#define rs o<<1|1typedef long long LL;typedef unsigned long long UL;typedef unsigned int UI;template
inline void gmax(T1 &a, T2 b) { if (b > a)a = b; }template
inline void gmin(T1 &a, T2 b) { if (b < a)a = b; }const int N = 0, M = 0, Z = 1e9 + 7, inf = 0x3f3f3f3f;template
inline void gadd(T1 &a, T2 b) { a = (a + b) % Z; }int casenum, casei;int n;int main(){ while(~scanf("%d",&n)){ int i, typ, sum, j; typ = 1; sum = 7; i = 12; while(1){ sum += typ; i ++; if(sum >= n) break; int flag = 1; for(int j = 1; j <= 4; j ++){ sum += typ + 1; i ++; //printf("%d %d\n", sum, i); if(sum >= n) {flag = 0; break;} } if(!flag) break; sum += typ + 2; i ++; if(sum >= n) break; typ ++; } if(n >= 8) printf("%d\n", i); else{ int ans; if(n == 1) ans = 6; else if(n == 2) ans = 8; else if(n == 3) ans = 9; else if(n == 4) ans = 10; else if(n == 5) ans = 11; else if(n == 6) ans = 12; else if(n == 7) ans = 12; printf("%d\n", ans); } } return 0;}/*【trick&&吐槽】【题意】【分析】【时间复杂度&&优化】*/

  

B. Domino Colorings

若已经知道了每个格子的颜色,那么可以DP判断是否能由某种骨牌铺成,设$dp[S]$表示轮廓线上$n$个点匹配状态为$S$是否可行即可。

现在不知道每个格子的颜色,那么需要DP这些颜色,设$f[i][j][c][v]$表示考虑到$(i,j)$,轮廓线上$n$个点颜色为$c$,$dp[S]$这个大小为$2^n$的布尔数组取值为$v$时的方案数。

当$n=6$时状态数也只有不到$2000$个,所以可以通过。

#include
#include
using namespace std;typedef unsigned long long ll;typedef pair
E;const int P=1000000007;int n,m,o,i,j,k,x,ans;map
f[2];map
::iterator it;inline void up(int&a,int b){a=a+b
first.first; ll dp=it->first.second; int w=it->second; int u=col>>j&1; int l=0; if(j)l=col>>(j-1)&1; int ecol=col^(u<
>x&1){ if(x>>j&1){ if(u==k)continue; ndp|=1ULL<<(x^(1<
>(j-1)&1)ndp|=1ULL<<(x^(1<<(j-1))); } up(f[o^1][E(ncol,ndp)],w); } } o^=1; } } for(it=f[o].begin();it!=f[o].end();it++)if(check(it->first.second))up(ans,it->second); printf("%d",ans);}

  

C. Counterquestion

暴力枚举$10!$种大小关系,然后求出每种的方案数即可。

#include
#include
#include
using namespace std;typedef long long ll;const int N=500;int n,i,j,m,q[N],id[N],cnt,rk[N];char a[N];ll f[5000000];void write(ll S){ static ll w[1000]; for(int i=n-1;i;i--){ w[i]=S%3; S/=3; } for(i=1;i
'); putchar(' '); } putchar(a[n]);}int main(){ scanf("%s",a+1); n=strlen(a+1); for(i=1;i<=n;i++){ if(!id[a[i]])id[a[i]]=++m; } for(i=1;i<=m;i++)q[i]=i; do{ for(i=1;i<=m;i++)rk[q[i]]=i; ll cur=0; for(i=1;i

  

D. Galaxy Center

首先假设$A$在$B$外层或同层,不然可以交换$AB$。

若$A$和$B$同层且距离不超过$5$,则此时直接走过去最优。

否则最优方案一定是将$A$往里走一层。

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;void fre() { }#define MS(x, y) memset(x, y, sizeof(x))#define ls o<<1#define rs o<<1|1typedef long long LL;typedef unsigned long long UL;typedef unsigned int UI;template
inline void gmax(T1 &a, T2 b) { if (b > a)a = b; }template
inline void gmin(T1 &a, T2 b) { if (b < a)a = b; }const int N = 40, M = 0, Z = 1e9 + 7, inf = 0x3f3f3f3f;template
inline void gadd(T1 &a, T2 b) { a = (a + b) % Z; }int casenum, casei;char a[N], b[N];LL v[N];struct P{ LL x, y;}va, vb;void mul(P &a){ ++a.x; a.y *= 3;}void div(P &a){ --a.x; a.y /= 3;}void add(P &a){ ++a.y; if(a.y == v[a.x])a.y -= v[a.x];}void sub(P &a){ --a.y; if(a.y < 0)a.y += v[a.x];}P know(char s[N]){ P now = {0, 0}; for(int i = 0; s[i]; ++i) { if(s[i] == 'c') { mul(now); } else if(s[i] == 'g') { div(now); } else if(s[i] == 's') { add(now); } else if(s[i] == 'a') { sub(now); } else {puts("s[i] = ?"); while(1);} } return now;}void print(P a){ printf("%lld %lld\n", a.x, a.y);}string GO(P a, P b){ if(a.x == b.x && a.y == b.y)return ""; string ans = ""; bool swp = 0; if(a.x < b.x) { swp = 1; swap(a, b); } LL by = b.y * v[a.x - b.x]; LL disS = by - a.y; if(disS < 0)disS += v[a.x]; LL disA = a.y - by; if(disA < 0)disA += v[a.x]; bool flag = 0; if(a.x == b.x) { if(disS < disA) { if(disS <= 5) { while(disS) { --disS; add(a); ans += 's'; } flag = 1; } } else if(disA < disS) { if(disA <= 5) { while(disA) { --disA; sub(a); ans += 'a'; } flag = 1; } } } if(!flag) { if(a.y % 3 == 1) { sub(a); ans += 'a'; } else if(a.y % 3 == 2) { add(a); ans += 's'; } div(a); ans += 'g'; } ans += GO(a, b); if(swp) { int len = ans.size(); for(int i = 0; i < len / 2; ++i) { swap(ans[i], ans[len - 1 - i]); } for(int i = 0; i < len; ++i) { if(ans[i] == 's')ans[i] = 'a'; else if(ans[i] == 'a')ans[i] = 's'; else if(ans[i] == 'c')ans[i] = 'g'; else if(ans[i] == 'g')ans[i] = 'c'; else {puts("ans[i] = ?"); while(1);} } } return ans;}int main(){ v[0] = 1; for(int i = 1; i <= 36; ++i)v[i] = v[i - 1] * 3; while(~scanf("%s%s", a, b)) { //print(know(a)); print(know(b)); cout << GO(know(a), know(b)) << endl; } return 0;}/*【trick&&吐槽】cccscscgcgcgccaaaccccssscccscacccacscsssccccccacscccscacccscsscccsscccccs【题意】【分析】【时间复杂度&&优化】*/

  

E. IBM 1403

预处理出$f[i][j]$表示模式串第$i$个位置之后第一个字符$j$的位置,对于每一行计算需要的最大时间即可。

#include
#include
#include
using namespace std;const int N=1000010;typedef long long ll;int L,n,i,j,cur,f[100010][130];char a[N],b[N];ll ans;int main(){ gets(a); L=strlen(a); for(i=L-1;~i;i--)f[L][a[i]]=i; for(i=L-1;~i;i--){ for(j=0;j<130;j++)f[i][j]=f[i+1][j]; f[i][a[i]]=i; } while(gets(b)){ n=strlen(b); int tmp=0; for(i=0;i
tmp)tmp=nxt; } tmp++; ans+=tmp; cur=(cur+tmp)%L; } printf("%lld",ans);}

  

F. Line Tracing

留坑。

 

G. The Queen and the Knight

当$n\leq 30$时,可以$O(n^5)$BFS出所有局面下的最优策略。

当$n>30$时,可以先逼近骑士,然后分类构造。

 

H. Product of Roots

\[\begin{eqnarray*}

f(x)&=&\prod_{i=1}^n(1+a_ix)\\
&=&\exp\left(\sum_{i=1}^n\ln(1+a_ix)\right)
\end{eqnarray*}\]

将$\ln(1+a_ix)$泰勒展开,有:

\[\begin{eqnarray*}

f(x)&=&\exp\left(\sum_{i=1}^n\ln(1+a_ix)\right)\\
&=&\exp\left(\sum_{i=1}^n\sum_{j\geq 1}\frac{(-1)^{j+1}}{j}x^ja_i^j\right)\\
&=&\exp\left(\sum_{j\geq 1}\frac{(-1)^{j+1}}{j}x^j\sum_{i=1}^n a_i^j\right)\\
&=&\exp\left(\sum_{j\geq 1}\frac{(-1)^{j+1}}{j}x^jA_j\right)\\
\end{eqnarray*}\]

对于$g$和$h$同理,则:

\[\begin{eqnarray*}

g(x)&=&\exp\left(\sum_{j\geq 1}\frac{(-1)^{j+1}}{j}x^jB_j\right)\\
h(x)&=&\exp\left(\sum_{j\geq 1}\frac{(-1)^{j+1}}{j}x^j\sum_{i=1}^n\sum_{k=1}^m a_i^jb_k^j\right)\\
&=&\exp\left(\sum_{j\geq 1}\frac{(-1)^{j+1}}{j}x^j\sum_{i=1}^n a_i^j\sum_{k=1}^m b_k^j\right)\\
&=&\exp\left(\sum_{j\geq 1}\frac{(-1)^{j+1}}{j}x^jA_jB_j\right)\\
&=&\exp\left(\sum_{j\geq 1}\frac{(-1)^{j+1}}{j}x^jC_j\right)
\end{eqnarray*}\]

多项式$\ln$求出所有$A_i$和$B_i$,令$C_i=A_iB_i$,然后按上式用多项式$\exp$计算$h$即可。

时间复杂度$O(n\log n)$。

#include
typedef long long ll;const int N=262144,K=17;int n,m,i,k,_;int a[N+10],b[N+10],c[N+10],tmp[N+10],tmp2[N+10];int P=998244353,G=3,g[K+1],ng[K+10],inv[N+10],inv2;inline int pow(int a,int b){int t=1;for(;b;b>>=1,a=(ll)a*a%P)if(b&1)t=(ll)t*a%P;return t;}inline void NTT(int*a,int n,int t){ for(int i=1,j=0;i
>=1,~j&s;); if(i
=P)B-=P; w=(ll)w*_w%P; } } if(t==-1)for(int i=0,j=inv[n];i
>1); int k=n<<1,i; for(i=0;i
>1); getln(b,tmp,n); int k=n<<1,i; for(i=0;i
<0)tmp[i]+=P;} if((++tmp[0])==P)tmp[0]=0; for(i=n;i

  

I. Safe Landing

按题意模拟。

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;void fre() { }#define MS(x, y) memset(x, y, sizeof(x))#define ls o<<1#define rs o<<1|1typedef long long LL;typedef unsigned long long UL;typedef unsigned int UI;template
inline void gmax(T1 &a, T2 b) { if (b > a)a = b; }template
inline void gmin(T1 &a, T2 b) { if (b < a)a = b; }const int N = 1e5 + 10, M = 0, Z = 1e9 + 7, inf = 0x3f3f3f3f;template
inline void gadd(T1 &a, T2 b) { a = (a + b) % Z; }int casenum, casei;char s[N];bool v[128];int main(){ while(~scanf("%s",s)) { MS(v, 0); int cnt = 0; for(int i = 0; s[i]; ++i) { if(!v[s[i]])++cnt; v[s[i]] = 1; } if(cnt <= 1)puts("X"); else if(cnt == 3) { if(!v['N'])puts("N"); else if(!v['S'])puts("S"); else if(!v['W'])puts("W"); else if(!v['E'])puts("E"); else while(1); } else if(cnt == 2) { if(v['N'] && v['W']) puts("SE"); else if(v['N'] && v['E'])puts("SW"); else if(v['S'] && v['W']) puts("NE"); else if(v['S'] && v['E'])puts("NW"); else puts("X"); } else while(1); } return 0;}/*【trick&&吐槽】【题意】【分析】【时间复杂度&&优化】*/

  

J. Perfect Square

取$20$个大质数,然后检查$x^2\bmod p=n$是否有解即可。

根据二次剩余,这等价于$n^{\frac{p-1}{2}}\bmod p=1$。

#include
#include
#include
#include
using namespace std;typedef long long ll;const int N=1000010;int n,i,cnt;char a[N];bool isprime(int n){ for(int i=2;i<=n/i;i++)if(n%i==0)return 0; return 1;}ll powmod(ll a,ll b,ll P){ ll t=1; for(;b;b>>=1,a=a*a%P)if(b&1)t=t*a%P; return t;}bool work(ll n,ll p){ if(n==0||n==1)return 1; if(powmod(n,p>>1,p)!=1)return 0; return 1;}bool check(int P){ ll ret=0; for(int i=1;i<=n;i++)ret=(ret*10+a[i]-'0')%P; return work(ret,P);}int main(){ scanf("%s",a+1); n=strlen(a+1); for(i=1000000000;;i++)if(isprime(i)){ if(!check(i))return puts("No"),0; cnt++; if(cnt>=20)return puts("Yes"),0; }}

  

转载于:https://www.cnblogs.com/clrs97/p/8636147.html

你可能感兴趣的文章
Topshelf 使用
查看>>
Linux --Apache服务搭建
查看>>
20145325张梓靖 实验三 "敏捷开发与XP实践"
查看>>
JavaScript面试题
查看>>
[转帖]架构师眼中的高并发架构
查看>>
ios的一些开源资源
查看>>
HTTP 错误 500.21 - Internal Server Error 解决方案
查看>>
Bucks sign Sanders to $44 million extension
查看>>
【PHP】Windows下配置用mail()发送邮件
查看>>
Nhibernate和EF的区别
查看>>
基于java spring框架开发部标1078视频监控平台精华文章索引
查看>>
人类简史
查看>>
java 设计模式学习
查看>>
【Python使用】使用pip安装卸载Python包(含离线安装Python包)未完成???
查看>>
一语道破项目管理知识体系五大过程组
查看>>
C# 备份、还原、拷贝远程文件夹
查看>>
在windows环境下运行compass文件出现的错误提示解决方案
查看>>
CSS常用样式--font
查看>>
恩如氏--蜗牛精华补水蚕丝面膜
查看>>
大工具-收藏
查看>>