生活随笔
收集整理的這篇文章主要介紹了
codeforces:812(div2):总结
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
前言
比較水的一場比賽
E題幾乎是一本通原題而我還是不會做qwq
A - Sagheer and Crossroads
有一個十字路口,給出四個路口的車是否可以左轉/右轉/直行,并且給出每個路口的行人是否可以通過,求是否出現車和人沖突的情況
閱讀理解題(其實只是我英語太差了),讀懂題意直接模擬即可
#include<bits/stdc++.h>
using namespace std
;
#define ll long long
#define debug(...) fprintf(stderr,__VA_ARGS__)
const int N
=5e5+100;
const int mod
=1e9+7;
const double eps
=1e-9;
inline ll
read(){ll
x(0),f(1);char c
=getchar();while(!isdigit(c
)){if(c
=='-')f
=-1;c
=getchar();}while(isdigit(c
)){x
=(x
<<1)+(x
<<3)+c
-'0';c
=getchar();}return x
*f
;
}int n
,m
;int a
[5][5],d
[4]={0,3,2,1};
bool vis
[5];
int main(){
#ifndef ONLINE_JUDGEfreopen("a.in","r",stdin);freopen("a.out","w",stdout);
#endiffor(int i
=1;i
<=4;i
++){for(int j
=1;j
<=4;j
++) a
[i
][j
]=read();}for(int i
=1;i
<=4;i
++){for(int j
=1;j
<=3;j
++){if(a
[i
][j
]){vis
[(i
+d
[j
]-1)%4+1]=1,vis
[i
]=1;}}}for(int i
=1;i
<=4;i
++){if(vis
[i
]&&a
[i
][4]){printf("YES");return 0;}}printf("NO\n");return 0;
}
B - Sagheer, the Hausmeister
給出一個n層的房屋,每層有m個房間,最左邊和最右邊有兩個樓梯
有一些房間的燈是開著的,求一條從第一層左樓梯開始的最短的不下樓的路徑,關掉所有的燈
n≤15,m≤100n \leq 15,m \leq 100n≤15,m≤100
dp入門水題,設計 dpi,0/1dp_{i,0/1}dpi,0/1? 表示從在第 i 層的左/右樓梯(本層的燈還沒有關)的最短路徑,枚舉關燈方式進行轉移即可
時間復雜度 O(n×m)O(n \times m)O(n×m)(瓶頸竟然在于輸入)
但是這題還WA了兩次…有一些特殊情況需要特判:
如果當前樓的上面一盞燈都沒有就不必繼續上樓了存在整棟樓沒有燈的情況
#include<bits/stdc++.h>
using namespace std
;
#define ll long long
#define debug(...) fprintf(stderr,__VA_ARGS__)
const int N
=5e5+100;
const int mod
=1e9+7;
const double eps
=1e-9;
inline ll
read(){ll
x(0),f(1);char c
=getchar();while(!isdigit(c
)){if(c
=='-')f
=-1;c
=getchar();}while(isdigit(c
)){x
=(x
<<1)+(x
<<3)+c
-'0';c
=getchar();}return x
*f
;
}int n
,m
;
int dp
[18][2];
int l
[18],r
[18];
int main(){
#ifndef ONLINE_JUDGEfreopen("a.in","r",stdin);freopen("a.out","w",stdout);
#endifint top(0);n
=read();m
=read()+2;for(int i
=n
;i
>=1;i
--){for(int j
=1;j
<=m
;j
++){int x(0);scanf("%1d",&x
);if(x
){if(!top
) top
=i
;if(!l
[i
]) l
[i
]=j
;r
[i
]=j
;}}}memset(dp
,0x3f,sizeof(dp
));dp
[1][0]=0;n
=top
;if(!top
){printf("0");return 0;}for(int i
=1;i
<n
;i
++){if(!l
[i
]){dp
[i
+1][0]=dp
[i
][0]+1;dp
[i
+1][1]=dp
[i
][1]+1;}else{dp
[i
+1][0]=min(dp
[i
][0]+2*(r
[i
]-1)+1,dp
[i
][1]+m
);dp
[i
+1][1]=min(dp
[i
][1]+2*(m
-l
[i
])+1,dp
[i
][0]+m
);}}int ans
=min(dp
[n
][0]+r
[n
]-1,dp
[n
][1]+m
-l
[n
]);printf("%d\n",ans
);return 0;
}
C - Sagheer and Nubian Market
給出 nnn 個元素的基本價格 aia_iai? ,如果你選擇了k個元素 ax1,ax2,...,axka_{x_1},a_{x_2},...,a_{x_k}ax1??,ax2??,...,axk??,那么每個元素的真實價格就是 axi+k?xia_{x_i}+k*x_iaxi??+k?xi?(換句話說就是加上總數量乘下角標)
現在有 sss 元錢,求最多能買到幾個元素
二分答案,二分后每個元素的真實價格就確定了,sort后取前 kkk 個看有沒有超過 sss 即可
#include<bits/stdc++.h>
using namespace std
;
#define ll long long
#define debug(...) fprintf(stderr,__VA_ARGS__)
const int N
=2e5+100;
const int mod
=1e9+7;
const double eps
=1e-9;
inline ll
read(){ll
x(0),f(1);char c
=getchar();while(!isdigit(c
)){if(c
=='-')f
=-1;c
=getchar();}while(isdigit(c
)){x
=(x
<<1)+(x
<<3)+c
-'0';c
=getchar();}return x
*f
;
}int n
,m
,s
;
ll a
[N
],b
[N
];
ll
calc(int k
){for(int i
=1;i
<=n
;i
++) b
[i
]=a
[i
]+1ll*i
*k
;sort(b
+1,b
+1+n
);ll
res(0);for(int i
=1;i
<=k
;i
++) res
+=b
[i
];return res
;
}
int main(){
#ifndef ONLINE_JUDGEfreopen("a.in","r",stdin);freopen("a.out","w",stdout);
#endifn
=read();s
=read();for(int i
=1;i
<=n
;i
++) a
[i
]=read();int st
=0,ed
=n
;while(st
<ed
){int mid
=(st
+ed
+1)>>1;if(calc(mid
)<=s
) st
=mid
;else ed
=mid
-1;}printf("%d %lld\n",st
,calc(st
));return 0;
}
D - Sagheer and Kindergarten
如果想自己做一下這道題,建議直接去原題面
有 nnn 個孩子和 mmm 個玩具,孩子會提出一共k個對玩具的要求,滿足如下性質:
如果一個孩子要求的玩具是閑置的(也就是不在任何一個孩子手中),他就會得到那個玩具,否則他就會一直等待每個孩子可能會要求得到若干個玩具,只有當其得到 所有玩具 時,才會滿意,并在玩一會玩具后返還所有的玩具,而在此之前會一直霸占著所有已有的玩具如果變得空閑的玩具被兩個孩子要求,會優先滿足靠前的要求如果一個孩子的某個要求沒有被滿足,他就不會再要求別的玩具如果一個孩子發現自己永遠也得不到滿足,就會開始哭保證在當前的k個要求中,沒有孩子在哭 有q個獨立的詢問,每次增加一條要求(不一定滿足第4條和第6條),求有多少個孩子在哭
真正的閱讀理解題(上面這一大陀已經是我部分精簡抽象后的結果),難點似乎就在于轉化題意,后面就比較顯然了
可以把對玩具的要求轉化為孩子之間的依賴關系
具體的,如果x要求玩具w,上一個要求玩具w的人是y,就連一條有向邊 y?>xy->xy?>x,表示只有y滿足之后x才能滿足
一個孩子哭泣,當且僅當他在某個環中
由于性質4和性質6,連成的圖一定是一個森林
每次判斷給出的新的依賴關系是否是返祖邊,如果是,這條鏈就會形成一個環,否則必然不會成環
判斷返祖不必lca,可以直接用dfs序判定子樹的方法,單次詢問 O(1)O(1)O(1)
#include<bits/stdc++.h>
using namespace std
;
#define ll long long
#define debug(...) fprintf(stderr,__VA_ARGS__)
const int N
=2e5+100;
const int mod
=1e9+7;
const double eps
=1e-9;
inline ll
read(){ll
x(0),f(1);char c
=getchar();while(!isdigit(c
)){if(c
=='-')f
=-1;c
=getchar();}while(isdigit(c
)){x
=(x
<<1)+(x
<<3)+c
-'0';c
=getchar();}return x
*f
;
}int n
,m
,k
,q
;
int bel
[N
];
struct node{int to
,nxt
;
}p
[N
<<1];
int fi
[N
],cnt
;
inline void addline(int x
,int y
){p
[++cnt
]=(node
){y
,fi
[x
]};fi
[x
]=cnt
;return;
}int du
[N
];
int siz
[N
],pos
[N
],tim
,dep
[N
];
void dfs(int x
,int f
){pos
[x
]=++tim
;dep
[x
]=dep
[f
]+1;siz
[x
]=1;for(int i
=fi
[x
];~i
;i
=p
[i
].nxt
){int to
=p
[i
].to
;dfs(to
,x
);siz
[x
]+=siz
[to
];}return;
}
int main(){
#ifndef ONLINE_JUDGEfreopen("a.in","r",stdin);freopen("a.out","w",stdout);
#endifmemset(fi
,-1,sizeof(fi
));cnt
=-1;n
=read();m
=read();k
=read();q
=read();for(int i
=1;i
<=k
;i
++){int x
=read(),y
=read();if(bel
[y
]) addline(bel
[y
],x
),du
[x
]++;bel
[y
]=x
; }for(int i
=1;i
<=n
;i
++){if(!du
[i
]) dfs(i
,0);}for(int i
=1;i
<=q
;i
++){int x
=read(),y
=read();int o
=bel
[y
];if(pos
[x
]<=pos
[o
]&&pos
[o
]<=pos
[x
]+siz
[x
]-1) printf("%d\n",siz
[x
]);else printf("0\n");}return 0;
}
E - Sagheer and Apple Tree
給定一個樹,第i個節點上有aia_iai?個蘋果
兩人輪流行動,每次可以選擇一個有蘋果的節點,進行下列行為之一:
如果是葉子節點,就吃掉節點上的一些蘋果如果不是葉子,就把節點上的一些蘋果移到他的一個兒子上 保證從根到所有葉子的距離的奇偶性相同
現在,后手方可以交換任意兩個節點(u,v)(u,v)(u,v)上的蘋果數,求能使雙方最優情況下后手獲勝的無序點對(u,v)(u,v)(u,v)的數量
ybt有一道情景幾乎一模一樣的題
然而還是并不會
qwq
感覺這個題的題解講的更加透徹
把葉子和到葉子距離為偶數的點染成黑色,距離為偶數的點染成白色
那么,每次操作其實就是使黑色節點的某一堆的石子增加或減少
那么和nim游戲的唯一區別就是這里還可以增加石子
但是其實并不影響,因為必敗方嘗試增加石子后,必勝方都可以把增加的石子減少回去
所以后手勝的充要條件和nim一樣,就是黑點權值異或和為0
然后合法點對就可以分類討論一下然后開個map隨便做了
#include<bits/stdc++.h>
using namespace std
;
#define ll long long
#define debug(...) fprintf(stderr,__VA_ARGS__)
const int N
=2e5+100;
const int mod
=1e9+7;
const double eps
=1e-9;
inline ll
read(){ll
x(0),f(1);char c
=getchar();while(!isdigit(c
)){if(c
=='-')f
=-1;c
=getchar();}while(isdigit(c
)){x
=(x
<<1)+(x
<<3)+c
-'0';c
=getchar();}return x
*f
;
}int n
;
struct node{int to
,nxt
;
}p
[N
<<1];
int fi
[N
],cnt
;
inline void addline(int x
,int y
){p
[++cnt
]=(node
){y
,fi
[x
]};fi
[x
]=cnt
;return;
}int num
[2];
int a
[N
],op
[N
],s
;
map
<int,int>mp
;
void dfs(int x
){if(fi
[x
]==-1){op
[x
]=1;return;}for(int i
=fi
[x
];~i
;i
=p
[i
].nxt
){int to
=p
[i
].to
;dfs(to
);op
[x
]=op
[to
]^1;} return;
}int main(){
#ifndef ONLINE_JUDGEfreopen("a.in","r",stdin);freopen("a.out","w",stdout);
#endifmemset(fi
,-1,sizeof(fi
));cnt
=-1;n
=read();for(int i
=1;i
<=n
;i
++) a
[i
]=read();for(int i
=2;i
<=n
;i
++) addline((int)read(),i
);dfs(1);for(int i
=1;i
<=n
;i
++){++num
[op
[i
]];if(op
[i
]) s
^=a
[i
];}if(s
==0){ll ans
=1ll*num
[0]*(num
[0]-1)/2+1ll*num
[1]*(num
[1]-1)/2;for(int i
=1;i
<=n
;i
++){if(op
[i
]) mp
[a
[i
]]++;}for(int i
=1;i
<=n
;i
++){if(!op
[i
]) ans
+=mp
[a
[i
]];}printf("%lld\n",ans
);}else{ll
ans(0);for(int i
=1;i
<=n
;i
++){if(op
[i
]) mp
[a
[i
]^s
]++;}for(int i
=1;i
<=n
;i
++){if(!op
[i
]) ans
+=mp
[a
[i
]];}printf("%lld\n",ans
);}return 0;
}
總結
以上是生活随笔為你收集整理的codeforces:812(div2):总结的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。