A
シミュレーションタイトル
考え
*最初に見つけ、その後、境界、最終的な出力を見つけます。そして、見つけ最小境界が最大値を割り当てる必要があります
コード
char ch[101][101],c;
int p,q,x,y;
signed main(){
int n=read(),m=read();
p=x=0x3f;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++){
cin>>c;
ch[i][j]=c;
if(c=='*'){
if(i<=p) p=i;
if(j<=x) x=j;
if(i>=q) q=i;
if(j>=y) y=j;
}
}
for(int i=p;i<=q;i++){
for(int j=x;j<=y;j++)
printf("%c",ch[i][j]);
puts("");
}
return 0;
}
B
考え
暴力は列挙することができます
コード
int a[5005],ans=inf;
signed main(){
int n=read(),x0=read();
for(int i=0;i<n;i++){
int x=read(),y=read();
if(x>y) swap(x,y);//ai可能大于bi
for(int j=x;j<=y;j++){
a[j]++;//枚举点
if(a[j]==n)
if(abs(j-x0)<ans) ans=abs(j-x0);//找最大距离
}
}
if(ans==inf) ans=-1;
printf("%d\n",ans);
return 0;
}
C
考え
それが同じであれば、各点と一点のみを参照し
、入力が四辺となるかどうかを確認する場合、前記2 (X \)\平行軸と他の二つの\(Y \)軸に平行
コード
struct Node{
int x,y;
}p[10];
signed main(){
for(int i=0;i<8;i++) scanf("%d%d",&p[i].x,&p[i].y);
bool flag=true;
for(int i=0;i<8;i++){
int cnt=0;
for(int j=0;j<8;j++ )
if(p[i].x==p[j].x&&p[i].y==p[j].y) cnt++;
if(cnt!=2){flag=false;break;}
}
if(flag==false) return puts("NO"),0;
int tx=0,ty=0;
for(int i=0;i<4;i++){
if(p[i*2].x==p[i*2+1].x&&p[i*2].y!=p[i*2+1].y) tx++;
if(p[i*2].x!=p[i*2+1].x&&p[i*2].y==p[i*2+1].y) ty++;
}
if(!(tx==2&&ty==2)) flag=false;
if(flag) printf("YES");
else printf("NO");
return 0;
}
D
木の直径を求めて、隣接行列は、ここで使用される\(DFS \)の要件を
考え
\(\ N-)点、\(N-1 \)側に2つの互いに素の最長の鎖の長さを求めることなく、この図ではバー、
だけがあるので\(N-1 \)エッジ、一定のようにリングが存在しない、
我々は各エッジを列挙することができ、図4に、このエッジは、二つの部分に分け、
ツリーの各部分の直径を見つけ、次いで生成物、
\(DFS \)の場合、記録時とツリーの最大長さチェーンの長さ
int dep,n,ch[maxn][maxn];//邻接矩阵
inline int dfs(int x,int y){
int maxx=0,maxx1=0,maxpath=0;
for(int i=1;i<=n;i++){
if(ch[i][x]&&i!=y){
int z=dfs(i,x);
if(maxpath<z) maxpath=z;
if(maxx<dep){
maxx1=maxx;
maxx=dep;
}
else if(maxx1<dep) maxx1=dep;
}
}
if(maxpath<maxx+maxx1) maxpath=maxx1+maxx;
dep=maxx+1;
return maxpath;
}
signed main(){
n=read();
for(int i=1;i<n;i++){
int x=read(),y=read();
ch[x][y]=ch[y][x]=1;
}
int ans=-1;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(ch[i][j]){
int a=dfs(i,j);
int b=dfs(j,i);
ans=max(ans,a*b);
}
printf("%d",ans);
return 0;
}
E
\(DP \)
が、3次元的に最適化することができます
質問の意味:
あなたの数を得た\(Nを\)から、\(1 \)する(N \)\形成\(T \)山と\(T-1 \)トラフ、ケースの総数。
アイデア:
酒のための問題を破壊する\(2 \時刻t-1 \) ポイントを回し、設定\(DPを[X] [Y ] [t]は\) 場合落下最後の点である\((X、Y)\ ) 場合表示されます\(のt \)ターニングポイントの合計数。だから、現在のポイントの2例があり、現在のポイントのいずれかの彼の大規模な、または彼より小さくよりも彼の高さに最初のポイント。
現在のポイント場合は\((x、y)は\ ) の前に表示されます\(のt \)場合は、ポイントを回し\(のt \)が偶数である、それはちょうど、現在の状態を現在のポイント以下の着弾点の前にポイントを言うことです私は任意の自然を維持したいだけ偶数現れる(T \)\次に、ここでターニングポイント
[DP [X] [Y \ ] [T] = \和(DP [X-1]〜[H] [T])(1 \ ルH <Y)\]
ただトップの前にポイントが現在のポイントに落ちると同時に、達成することができます
\ [DP [X] [Y
] [T + 1] = \和(DP [X] [H] [T])(Y <H \ LE 4)\] 場合(Tを\)\奇数され、同じと
\ [DP [X] [Y] [T] = \和(DP [X-1]〜[H] [T])(Y <H \ LE 4); \]
\ [DP [X] [Y] [T + 1] = \和(DP [X-1]〜[H] [T])(1 \ルH <Y)\]
もちろん、特定のターニングポイントの始まりが高まっています。
コード
int dp[25][5][25];
signed main(){
for(int i=1;i<=3;i++) dp[1][i][0]=1;
for(int x=2;x<22;x++)
for(int y=1;y<=4;y++)
for(int t=0;t<21;t++)
for(int h=1;h<=4;h++){
if(x==2){
if(y>h){
if(t%2) dp[2][y][t+1]+=dp[1][h][t];
else dp[2][y][t]+=dp[1][h][t];
}
}
else{
if(t%2){
if(h>y) dp[x][y][t]+=dp[x-1][h][t];
else if(h<y) dp[x][y][t+1]+=dp[x-1][h][t];
}
else{
if(h<y) dp[x][y][t]+=dp[x-1][h][t];
else if(h>y) dp[x][y][t+1]+=dp[x-1][h][t];
}
}
}
int n=read(),t=read();
if(t*2+1>n||n>6*t+1) return puts("0"),0;
int ans=0;
for(int i=1;i<=4;i++)
ans+=dp[n][i][2*t-1];
printf("%d",ans);
return 0;
}