2014 ACM/ICPC Asia Regional Xi'an Online
A. Post Robot
把每种单词都kmp跑一遍,顺序输出即可
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <map>
#include <cstring>
#include <cmath>
#include <queue>
#include <set>
#include <vector>
#include <iterator>
#include <string>
#include <deque>
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define per(i,a,b) for(int i=a;i>=b;--i)
#define pb push_back
#define MP make_pair
#define fr first
#define sc second
#define PII pair<int,int>
#define VI vector<int>
typedef long long ll;
typedef unsigned long long ull;
inline int read() {
char c=getchar();int x=0,f=1;
while(!isdigit(c)){if(f=='-')f=-1;c=getchar();}
while(isdigit(c)){x=x*10+c-'0';c=getchar();}
return x*f;
}
const int N = 1000500;
using namespace std;
int n;
string s,t,s1="Apple",s2="iPhone",s3="iPod",s4="iPad",s5="Sony";
int nxt[N],vis[N];
void kmp_pre(string s) {
int i,j,m=s.size();
j=nxt[0]=-1;
i=0;
while(i<m){
while(-1!=j&&s[i]!=s[j])j=nxt[j];
nxt[++i]=++j;
}
}
void kmp(string s,string t,int f) {
int i,j,n=s.size(),m=t.size();
i=j=0;
while(i<n){
while(-1!=j&&s[i]!=t[j])j=nxt[j];
++i;++j;
if(j>=m) {
//printf("%d ",i);
vis[i] = f;
j=nxt[j];
}
}
}
int main() {
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
memset(vis,-1,sizeof(vis));
int f=0;
while(getline(cin,t)){
if(f) s+=" ";f=1;
s+=t;
}
kmp_pre(s1); kmp(s,s1,0);
kmp_pre(s2); kmp(s,s2,0);
kmp_pre(s3); kmp(s,s3,0);
kmp_pre(s4); kmp(s,s4,0);
kmp_pre(s5); kmp(s,s5,1);
rep(i,1,s.size())
if(vis[i]==0) puts("MAI MAI MAI!");
else if(vis[i]==1) puts("SONY DAFA IS GOOD!");
return 0;
}
E. Game
手推了几组,找规律的。把每一堆的大小都异或起来就星了。
#include <cstdio>
#include <algorithm>
#include <map>
#include <cstring>
#include <cmath>
#include <queue>
#include <set>
#include <vector>
#include <iterator>
#include <string>
#include <deque>
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define per(i,a,b) for(int i=a;i>=b;--i)
#define pb push_back
#define MP make_pair
#define fr first
#define sc second
#define PII pair<int,int>
#define VI vector<int>
typedef long long ll;
typedef unsigned long long ull;
inline int read() {
char c=getchar();int x=0,f=1;
while(!isdigit(c)){if(f=='-')f=-1;c=getchar();}
while(isdigit(c)){x=x*10+c-'0';c=getchar();}
return x*f;
}
using namespace std;
int n,x;
int main() {
while(scanf("%d",&n)!=EOF){
int ans=0;
rep(i,1,n){
int x=read();ans^=x;
}
if(!ans)puts("Lose");
else puts("Win");
}
return 0;
}
F. Dice
直接从123456开始bfs出到每种状态的距离即可。查询时,替换下标即可。
#include <cstdio>
#include <algorithm>
#include <map>
#include <cstring>
#include <cmath>
#include <iostream>
#include <queue>
#include <set>
#include <vector>
#include <iterator>
#include <string>
#include <deque>
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define per(i,a,b) for(int i=a;i>=b;--i)
#define pb push_back
#define MP make_pair
#define fr first
#define sc second
#define PII pair<int,int>
#define VI vector<int>
typedef long long ll;
typedef unsigned long long ull;
const int N = 654321 + 10;
inline int read() {
char c=getchar();int x=0,f=1;
while(!isdigit(c)){if(f=='-')f=-1;c=getchar();}
while(isdigit(c)){x=x*10+c-'0';c=getchar();}
return x*f;
}
using namespace std;
int hs(string s) {
int hs = 0;
for(int i=0;i<6;++i) hs = hs*10 + (s[i]-'0');
return hs;
}
string t;
string fhs(int x) {
t.clear();
while(x) {
t += (char)(x%10+'0');
x/=10;
}
reverse(t.begin(),t.end());
return t;
}
string tx,tx2;
int rt1(int x) {
tx = fhs(x);
tx2 = tx;
tx2[2-1] = tx[3-1];
tx2[4-1] = tx[2-1];
tx2[1-1] = tx[4-1];
tx2[3-1] = tx[1-1];
return hs(tx2);
}
int rt2(int x) {
tx = fhs(x);
tx2 = tx;
tx2[2-1] = tx[4-1];
tx2[3-1] = tx[2-1];
tx2[1-1] = tx[3-1];
tx2[4-1] = tx[1-1];
return hs(tx2);
}
int rt3(int x) {
tx = fhs(x);
tx2 = tx;
tx2[2-1] = tx[5-1];
tx2[6-1] = tx[2-1];
tx2[1-1] = tx[6-1];
tx2[5-1] = tx[1-1];
return hs(tx2);
}
int rt4(int x) {
tx = fhs(x);
tx2 = tx;
tx2[2-1] = tx[6-1];
tx2[5-1] = tx[2-1];
tx2[1-1] = tx[5-1];
tx2[6-1] = tx[1-1];
return hs(tx2);
}
int dis[N],vis[N];
void bfs(string s) {
memset(dis,-1,sizeof(dis));
memset(vis,0,sizeof(vis));
int u = hs(s);
dis[u] = 0;
queue<int> q;
q.push(u);
vis[u]=1;
while(!q.empty()) {
int u = q.front(); q.pop();
int tu = u;
tu = rt1(u);
if(!vis[tu]) {
vis[tu] = 1;
q.push(tu);
dis[tu] = dis[u] + 1;
}
tu = rt2(u);
if(!vis[tu]) {
vis[tu] = 1;
q.push(tu);
dis[tu] = dis[u] + 1;
}
tu = rt3(u);
if(!vis[tu]) {
vis[tu] = 1;
q.push(tu);
dis[tu] = dis[u] + 1;
}
tu = rt4(u);
if(!vis[tu]) {
vis[tu] = 1;
q.push(tu);
dis[tu] = dis[u] + 1;
}
}
}
int n,a[10],b[10];
map<int,int> c;
int main() {
string s = "123456";
bfs(s);
while(scanf("%d%d%d%d%d%d",&a[1],&a[2],&a[3],&a[4],&a[5],&a[6])!=EOF) {
scanf("%d%d%d%d%d%d",&b[1],&b[2],&b[3],&b[4],&b[5],&b[6]);
c.clear();
rep(i,1,6) c[a[i]] = i;
int hs = 0;
rep(i,1,6)hs=hs*10+c[b[i]];
printf("%d\n",dis[hs]);
}
return 0;
}
H. Number Sequence
一开始想起一道题,觉得要从高位到低位分治贪心。然后发现过的人有点多啊。就开始找规律。。。于是顺利浪费了大量时间。。。首先发现最大值就是\(n*(n+1)\) ,而每一个值都可以用一些\(2^i-1\)组合成,于是我们从大到小贪心的把每个数都异或成\(2^i-1\)中的尽可能大的值即可
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <map>
#include <cstring>
#include <cmath>
#include <queue>
#include <set>
#include <vector>
#include <iterator>
#include <string>
#include <deque>
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define per(i,a,b) for(int i=a;i>=b;--i)
#define pb push_back
#define MP make_pair
#define fr first
#define sc second
#define PII pair<int,int>
#define VI vector<int>
typedef long long ll;
typedef unsigned long long ull;
const int N = 1e6 +100000;
inline int read() {
char c=getchar();int x=0,f=1;
while(!isdigit(c)){if(f=='-')f=-1;c=getchar();}
while(isdigit(c)){x=x*10+c-'0';c=getchar();}
return x*f;
}
using namespace std;
ll n;
ll a[N],b[N];
int vis[N];
void solve() {
memset(vis,0,sizeof(vis));
for(int i=n;i>=0;--i) {
int e = 0;
for(ll j=20;j>=0;--j) {
e=(1<<j)-1;
if(!vis[(e^i)]&&(e^i)<=n) {
vis[(e^i)]=1;
b[i] = (e^i);
break;
}
}
}
}
int main() {
while(scanf("%lld",&n)!=EOF){
rep(i,0,n)a[i]=read();
solve();int f=0;
printf("%lld\n",(n+1ll)*n);
rep(i,0,n) {
if(f)printf(" ");f=1;
printf("%lld",b[a[i]]);
}puts("");
}
return 0;
}
I. 233 Matrix
发现n非常小,m很大,于是想到矩阵快速幂,推一下就ok了
#include <cstdio>
#include <algorithm>
#include <map>
#include <cstring>
#include <cmath>
#include <queue>
#include <set>
#include <vector>
#include <iterator>
#include <string>
#include <deque>
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define per(i,a,b) for(int i=a;i>=b;--i)
#define pb push_back
#define MP make_pair
#define fr first
#define sc second
#define PII pair<int,int>
#define VI vector<int>
#define rg register
typedef long long ll;
typedef unsigned long long ull;
const ll mod = 10000007;
inline int read() {
char c=getchar();int x=0,f=1;
while(!isdigit(c)){if(f=='-')f=-1;c=getchar();}
while(isdigit(c)){x=x*10+c-'0';c=getchar();}
return x*f;
}
using namespace std;
ll ans[20][20],c[20][20],d[20][20];
inline void mul(ll a[][20], ll b[][20], int n){
for(rg int i=1;i<=n;++i)
for(int j=1;j<=n;++j)ans[i][j]=0,c[i][j]=a[i][j],d[i][j]=b[i][j];
for(rg int i=1;i<=n;++i)
for(rg int k=1;k<=n;++k)if(c[i][k])
for(rg int j=1;j<=n;++j)if(d[k][j]){
ans[i][j] = (ans[i][j] + (c[i][k]*d[k][j]))%mod;
}
for(rg int i=1;i<=n;++i)
for(rg int j=1;j<=n;++j)a[i][j]=ans[i][j];
}
ll E[20][20],A[20][20];
inline void mx_pow(ll A[][20],ll b,int n) {
while(b) {
if(b&1) mul(E,A,n);
mul(A,A,n);
b>>=1LL;
}
}
int n;
ll m,a[20];
int main() {
while(scanf("%d%lld",&n,&m)!=EOF) {
memset(A,0,sizeof(A));
memset(E,0,sizeof(E));
rep(i,1,n) a[i] = read();
a[n+1] = 233; a[n+2] = 1;
rep(i,1,n+2)E[i][i] = 1;
rep(i,1,n)rep(j,1,i) A[i][j] = 1;
rep(i,1,n)A[i][n+1]=1;
A[n+1][n+1] = 10; A[n+1][n+2] = 3;
A[n+2][n+2]=1;
mx_pow(A,m,n+2);
ll res = 0;
rep(i,1,n+2) res = (res + (E[n][i]*a[i])%mod)%mod;
printf("%lld\n",res);
}
return 0;
}