ラウンド607
A
問題の意味
サフィックスに従い、判決からどの言語
思考
水問題
コード
#include<bits/stdc++.h>
using namespace std;
const int MAX=1e3+3;
char s[MAX];
int main()
{
int T;
cin>>T;
while(T--)
{
scanf("%s",s);
int len=strlen(s);
if(s[len-2]=='p'&&s[len-1]=='o')
{
printf("FILIPINO\n");
continue;
}
if(s[len-4]=='d'&&s[len-3]=='e'&&s[len-2]=='s'&&s[len-1]=='u')
{
printf("JAPANESE\n");
continue;
}
if(s[len-4]=='m'&&s[len-3]=='a'&&s[len-2]=='s'&&s[len-1]=='u')
{
printf("JAPANESE\n");
continue;
}
if(s[len-5]=='m'&&s[len-4]=='n'&&s[len-3]=='i'&&s[len-2]=='d'&&s[len-1]=='a')
{
printf("KOREAN\n");
continue;
}
}
}
B
問題の意味
二つの文字列に、B、任意の交換の文字の可能な組(一回のみの交換)、彼はそのようなかどうかを尋ねA辞書順未満B
思考
接尾辞での処理の前に貪欲、小さいより良い文字分前から背中にして、十分に交換するかどうかを決定します。これは、出力を比較するために切り替えた後、最高でなければなりません。
コード
#include<bits/stdc++.h>
using namespace std;
const int MAX=5e3+3;
char s[MAX],c[MAX],minn[MAX];
int index[MAX];
int main()
{
int T;
cin>>T;
while(T--)
{
scanf("%s%s",s,c);
int lens=strlen(s);
minn[lens-1]=s[lens-1];
index[lens-1]=lens-1;
for(int i=lens-2; i>0; i--)
{
index[i]=index[i+1];
minn[i]=minn[i+1];
if(s[i]<minn[i+1])
{
index[i]=i;
minn[i]=s[i];
}
}
for(int i=0; i<lens-1; i++)
if(s[i]>minn[i+1])
{
swap(s[i],s[index[i+1]]);
break;
}
if(strcmp(s,c)<0)
printf("%s\n",s);
else
printf("---\n");
}
}
C
問題の意味
文字列に1,2,3組成物。カーソル、各動作のための右のいずれかにカーソルが移動をシミュレートし、その後カーソルの周りの文字列に切断SLおよびSRは、SRでSL [後ペーストSL最後のビット]回。動作Qは、xはこの文字列の時間長の後に、出力1E9 + 7 MOD。
思考
以下のように見えるが、法を見つけることですが、実際にはライン上に暴力をシミュレートしました。文字がより多くの合計を記録する必要はありませんので、すべてのアクションは、右への唯一の動きであるので、Xの数ヶ月。従ってアナログ複雑さO(X) 。
コード
#include<bits/stdc++.h>
using namespace std;
const int MAX=2e6+6;
const int mod=1e9+7;
char s[MAX];
int main()
{
int T;
cin>>T;
while(T--)
{
int x;
scanf("%d%s",&x,s+1);
int len=strlen(s+1);
int res=len;
for(int i=1; i<=x; i++)
{
if(s[i]=='1')continue;
int cnt=s[i]-'1';
int cur=(res-i+mod)%mod;
if(len<x)
{
len+=cur;
for(int j=1;j<=cnt;j++)
for(int k=i+1; k<=len&&k+j*cur<=x; k++)
s[k+j*cur]=s[k];
}
res=((res+cur*cnt*1ll)%mod+mod)%mod;
}
printf("%d\n",(res+mod)%mod);
}
}
D
問題の意味
文字行列、にA、Pの設定。各操作から選択することができ、1×K個のセグメントまたはK×1期、および拡張期の期間が選択なっており、時間の必要最小数として全体マトリックス全体とすることができるように、ダウンしているか、左右の任意の長さを延長しますなりAは。
思考
もちろん、答えが存在する場合は、[0,4]の間。ラインジャッジは、列のように見えるキーを押し、最初の文は、その後、文ではなく、全体の行/列ない............エッジ計算回答が取る分とすることができます。
コード
#include<bits/stdc++.h>
using namespace std;
const int MAX=66;
char G[MAX][MAX];
int main()
{
int T;
cin>>T;
while(T--)
{
int n,m,res=MAX,cnt=0;
scanf("%d%d",&n,&m);
for(int i=0; i<n; i++)
scanf("%s",G[i]);
for(int i=0; i<n; i++)
{
bool flag1=1,flag2=0;
for(int j=0; j<m; j++)
{
flag1&=(G[i][j]=='A');
flag2|=(G[i][j]=='A');
cnt+=(G[i][j]=='A');
}
if(flag1)
{
if(i==0||i==n-1)
res=min(res,1);
else
res=min(res,2);
}
else
{
if(!flag2)continue;
if(G[i][0]=='A'||G[i][m-1]=='A')
{
if(i==0||i==n-1)
res=min(res,2);
else
res=min(res,3);
}
else
{
if(i==0||i==n-1)
res=min(res,3);
else
res=min(res,4);
}
}
}
if(cnt==n*m)
{
printf("0\n");
continue;
}
for(int j=0; j<m; j++)
{
bool flag1=1,flag2=0;
for(int i=0; i<n; i++)
{
flag1&=(G[i][j]=='A');
flag2|=(G[i][j]=='A');
}
if(flag1)
{
if(j==0||j==m-1)
res=min(res,1);
else
res=min(res,2);
}
else
{
if(!flag2)continue;
if(G[0][j]=='A'||G[n-1][j]=='A')
{
if(j==0||j==m-1)
res=min(res,2);
else
res=min(res,3);
}
else
{
if(j==0||j==m-1)
res=min(res,3);
else
res=min(res,4);
}
}
}
if(res==MAX)
printf("MORTAL\n");
else
printf("%d\n",res);
}
}
E
問題の意味
加重ツリーに2Kノード、K木のこの人分配ノードで、ヒトおよび最大値と割当要求の最小値の両方のための各距離。
思考
これは、最小に近い2人のように、可能な限り2人の最大のことをそれぞれ意志考えられます。だから、最初と表記木の重心を見つけるRTを。それは考えることができ、室温つのノードの違い、(必ずしも二つのサブツリー)ツリーを左及び右のセクションに分割されている1。このモデルを考えてみましょう。
最大は自分の一部とペアになっていない左に対するすべての権利、とペアになって、あなたはすべてのノードがすることの最大値を見つけることができます室温距離をと。
各パーツの最小値は、自給可能としてあります。あなたは考えることができますから、RT開始トラバース、木の子ノードの数が偶数であれば、さらに良いの特定の自給エッジよりRTので、このサブツリーのも、右側には寄与していなければなりません。サブツリーノードが奇数である場合、それは、サブツリーが接続されている必要があり、自己完結型であってはならない室温で。そして、問題は、サブ問題に分解することができます。ノード求めて各サブ質問Xのすべてのサブ木の貢献を。ボーダーは、リーフノードは、パリティ法に沿って、親ノードに接続する必要があり、リーフノードです。
コード
#include<bits/stdc++.h>
using namespace std;
const int MAX=2e5+5;
typedef long long ll;
struct Edge
{
int to,val,nxt;
}edges[MAX<<1];
int head[MAX],siz[MAX],mx_son_siz[MAX],n,tot,rt;
ll minn,maxx;
inline void addedge(int u,int v,int w)
{
edges[tot].to=v;
edges[tot].val=w;
edges[tot].nxt=head[u];
head[u]=tot++;
}
void getroot(int x,int fa)
{
siz[x]=1;
mx_son_siz[x]=0;
for(int i=head[x];i!=-1;i=edges[i].nxt)
{
int v=edges[i].to;
if(v==fa)continue;
getroot(v,x);
siz[x]+=siz[v];
mx_son_siz[x]=max(mx_son_siz[x],siz[v]);
}
mx_son_siz[x]=max(mx_son_siz[x],n-siz[x]);
if(!rt||mx_son_siz[x]<mx_son_siz[rt])
rt=x;
}
void dfs(int x,int fa,ll sum,int w)
{
siz[x]=1;
for(int i=head[x];i!=-1;i=edges[i].nxt)
{
int v=edges[i].to;
if(v==fa)continue;
dfs(v,x,sum+edges[i].val,edges[i].val);
siz[x]+=siz[v];
}
if(siz[x]&1)
minn+=w;
maxx+=sum;
}
void init()
{
for(int i=1;i<=n;i++)
head[i]=-1;
rt=tot=0;
minn=maxx=0ll;
}
int main()
{
int T;
cin>>T;
while(T--)
{
scanf("%d",&n);
n<<=1;
init();
for(int i=1;i<n;i++)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
addedge(u,v,w);
addedge(v,u,w);
}
getroot(1,-1);
dfs(rt,-1,0,0);
printf("%I64d %I64d\n",minn,maxx);
}
}