CCPC-Wannafly 自閉day5

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;
}
View Code

 F:

有難度。既然正向考慮直接計數很難,那麼反着考慮,如果總方案減去不合法方案數就是答案數。

某點連出的每一條黑邊都可以與此點連出的每一條白邊構成不合法三角環。設a[i] = 黑邊數×百邊數 , a[i]是此點貢獻的不合法方案數。

由於每條邊被調用2次,所以要除以2。

C_{n}^{3} - {\frac{\sum_{{i= 1}}^{n} a_i}{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;
}
View Code

 

 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;
}
View Code

 

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;
}
View Code

 

 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;
} 
View Code
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章