C:
主要在於讀題,然後貪心即可。最多的:劇毒打嘲諷,普通打聖盾。最少與最多情況相反。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int a[4008],b[48],c[48];
char s[4008];
int T,n;
void solve(){
scanf("%d%d%d%d%d",&n,&b[1],&b[2],&b[3],&b[4]);
scanf("%s",s);
c[1] = b[1],c[2] = b[2],c[3] = b[3],c[4] = b[4];
int Max = 0,Min = 0;
for(int i = 1;i <= n;i ++){
if(s[i - 1] == '1'){
if(b[3]) b[3] --,Max ++;
else if(b[4]) b[4] --,b[3] ++;
else if(b[1]) b[1] --,Max ++;
else if(b[2]) b[2] --,b[1] ++;
}
else{
if(b[4]) b[4] --,b[3] ++;
else if(b[3]) continue;
else if(b[2]) b[2] --,b[1] ++;
else continue;
}
}
for(int i = 1;i <= n;i ++){
if(s[i - 1] == '1'){
if(c[4]) c[4] --,c[3] ++;
else if(c[3]) c[3] --,Min ++;
else if(c[2]) c[2] --,c[1] ++;
else if(c[1]) Min ++,c[1] --;
}
else {
if(c[3]) continue;
else if(c[4]) c[4] --,c[3] ++;
else if(c[1]) continue;
else if(c[2]) c[2] --,c[1] ++;
}
}
cout << Max << " " << Min << endl;
return;
}
int main(){
cin >> T;
while(T --)
solve();
return 0;
}
F:
有難度。既然正向考慮直接計數很難,那麼反着考慮,如果總方案減去不合法方案數就是答案數。
某點連出的每一條黑邊都可以與此點連出的每一條白邊構成不合法三角環。設a[i] = 黑邊數×百邊數 , a[i]是此點貢獻的不合法方案數。
由於每條邊被調用2次,所以要除以2。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
ll a,b,c,p,d,n,ans;
void solve(){
cin >> n >> a >> b >> c >> p >> d;
ll ans = n * (n - 1) * (n - 2) / 6,t = 0;
for(int i = 1;i <= n;i ++){
int x = 0,y = 0;
for(int j = 1;j <= n;j ++)
{
if(i == j) continue;
(a * (i + j) * (i + j) + b * (i - j) * (i - j) + c) % p > d ? x ++ : y ++;
}
t += x * y;
}
cout << ans - t / 2;
return;
}
int main(){
solve();
return 0;
}
K:
越大的數對答案貢獻越大,那麼越靠近數列中間,將其覆蓋的區間越多。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
void solve(){
int n,t = 1,f = 0;
cin >> n;
f = n % 2 ? n - 1 : n;
for(int i = 1;i <= n; i ++){
if(i <= n / 2){
printf("%d ",t);
t += 2;
}
else if(n % 2 == 1 && i == n / 2 + 1){
printf("%d ",n);
}
else {
printf("%d ",f);
f -= 2;
}
}
return;
}
int main(){
solve();
return 0;
}
L:
bfs,注意判斷馬被卡的情況。第一發格式錯誤,是因爲行末輸出多餘的空格。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int MAXN = 10001;
char ma[201][201];
int ans[201][201];
int n,m,sx,sy;
struct hh{
int x,y,cnt;
}a[MAXN];
queue<hh>q;
int X[] = {1,2,1,2,-1,-2,-1,-2};
int Y[] = {-2,-1,2,1,-2,-1,2,1};
bool pd(int x,int y){
if(x >= 1 && x <= n && y >= 1 && y <= m && ma[x][y] == '.' && ans[x][y] == -1) return true;
return false;
}
bool pd_b(int X,int Y,int x,int y){
if(X == -2 && ma[x - 1][y] != 'X') return true;
else if(X == 2 && ma[x + 1][y] != 'X') return true;
else if(Y == -2 && ma[x][y - 1] != 'X') return true;
else if(Y == 2 && ma[x][y + 1] != 'X') return true;
else return false;
}
void bfs(){
q.push((hh){sx,sy,0});
ans[sx][sy] = 0;
while(!q.empty()){
hh x = q.front();
q.pop();
for(int i = 0;i < 8;i ++){
int fx = X[i] + x.x;
int fy = Y[i] + x.y;
if(pd(fx,fy) && pd_b(X[i],Y[i],x.x,x.y)){
q.push((hh){fx,fy,x.cnt + 1});
ans[fx][fy] = x.cnt + 1;
}
}
}
return;
}
void solve(){
memset(ans,-1,sizeof(ans));
cin >> n >> m;
for(int i = 1;i <= n;i ++)
scanf("%s",ma[i] + 1);
for(int i = 1;i <= n;i ++){
for(int j = 1;j <= m;j ++){
if(ma[i][j] == 'M') sx = i,sy = j;
}
}
bfs();
for(int i = 1;i <= n;i ++){
for(int j = 1;j <= m;j ++){
printf("%d",ans[i][j]);
if(j != m) printf(" ");
}
printf("\n");
}
return;
}
int main(){
solve();
return 0;
}
M:
這題說的不就是我嗎2333。
注意有的選手可能ac某題後依然提交代碼。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const ll M1 = 998244353;
const ll M2 = 1000000;
ll n,m,w;
ll ans[20001];
ll ti[16];
struct hh{
ll cnt[12][3],num,jiao;
}a[2001];
void solve(){
ll x,y,c;
cin >> n >> m >> w;
for(int i = 1;i <= w;i ++){
scanf("%lld%lld%lld",&x,&y,&c);
a[x].jiao ++;
if(c == 0){
a[x].cnt[y][0] ++;
a[x].cnt[y][2]= max(a[x].cnt[y][2],a[x].cnt[y][0]);
}
else {
a[x].cnt[y][1] ++;
a[x].cnt[y][0] = 0;
if(a[x].cnt[y][1] == 1){
ti[y] ++;
a[x].num ++;
}
}
}
for(int i = 1;i <= n;i ++){
if(a[i].jiao == 0) ans[i] = M1;
else if(a[i].num == 0) ans[i] = M2;
else if(a[i].num == m) ans[i] = 0;
else for(int j = 1;j <= m;j ++){
ans[i] += a[i].cnt[j][2] * a[i].cnt[j][2];
if(!a[i].cnt[j][1]){
ans[i] += a[i].cnt[j][2] * a[i].cnt[j][2];
if(ti[j]){
ans[i] += 20;
if(ti[j] >= n / 2) ans[i] += 10;
}
}
}
}
for(int i = 1;i <= n;i ++) printf("%lld\n",ans[i]);
return;
}
int main(){
solve();
return 0;
}