1. 程式人生 > 實用技巧 >Educational Codeforces Round 89 (Rated for Div. 2)

Educational Codeforces Round 89 (Rated for Div. 2)

Educational Codeforces Round 89 (Rated for Div. 2)

這套題總的來說都不是很難,和昨天寫的那套有一定的相似程度,就是演算法比較少,思維比較多。
A B 沒有昨天做的那麼順,還是卡了一會,尤其是B,還把題目看錯了
C 題倒是做的比較順,但是花的時間還是長了一點點
D 題不是很難,花的時間過於多了,導致E題結束之後才寫完
這場的ABCDE都可以補一下,沒什麼演算法,主要靠思維+細心觀察

A. Shovels and Swords

這個假設 \(x\) 個 sword,\(y\) 個 shovel,

那麼最後就是 $2*x+y<=a$ \(x+2*y<=b\)

所以 \(x+y<=(a+b)/3\)

所以就可以把 \(x+y\) 求出來了,但是注意要和 \(a、b\) 取一個min。

#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
#define inf64 0x3f3f3f3f3f3f3f3f
#define debug(x) printf("debug:%s=%d\n",#x,x);
//#define debug(x) cout << #x << ": " << x << endl
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 5e5+10;
 
int main(){
    int t;
    scanf("%d",&t);
    while(t--){
        int n,m;
        scanf("%d%d",&n,&m);
        int ans=min((n+m)/3,min(n,m));
        printf("%d\n",ans);
    }
    return 0;
}

B. Shuffle

題目大意:

首先在 \(x\) 位置有一個1,你有 \(m\) 次操作,對於第 \(i\) 次操作,你可以交換 \([li,ri]\) 的任意兩個數,注意這兩個數可以相同,也就是說你可以不進行交換。問最後可以出現1的位置有多少個?

題解:

這個其實就是一個區間不斷往外擴充套件,第一次的區間就是 \([x,x]\) ,之後的操作區間如果和之前得到的區間有重疊,那麼就可以加入之前的這個區間,最後輸出區間的長度即可。

#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
#define inf64 0x3f3f3f3f3f3f3f3f
#define debug(x) printf("debug:%s=%d\n",#x,x);
//#define debug(x) cout << #x << ": " << x << endl
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 5e5+10;
 
int main(){
    int t;
    scanf("%d",&t);
    while(t--){
        int n,x,m;
        scanf("%d%d%d",&n,&x,&m);
        int l=x,r=x;
        for(int i=1;i<=m;i++){
            int a,b;
            scanf("%d%d",&a,&b);
            if((a<=r&&a>=l)||(b<=r&&b>=l)||(b>=r&&a<=r)) {
                l=min(l,a);
                r=max(r,b);
            }
        }
        printf("%d\n",r-l+1);
    }
}

C. Palindromic Paths

題目大意:

給你一個 \(n*m\) 的矩陣,從 \((1,1)\) 開始走,每一步只能往右或者往下走,最後走到 \((n,m)\) ,給你這個矩陣每一個位置的值,這個值取0或者1,你可以對這個矩陣的值進行改變,問最少改變多少個值,可以讓第一步的位置和最後一步的位置的值相同,第二步的位置和倒數第二個位置的值相同,以此類推。

題解:

這個不好講,看程式碼吧

#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
#define inf64 0x3f3f3f3f3f3f3f3f
#define debug(x) printf("debug:%s=%d\n",#x,x);
//#define debug(x) cout << #x << ": " << x << endl
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn =55;
int a[maxn][maxn],num[110],sum[110];
 
int main(){
    int t;
    scanf("%d",&t);
    while(t--){
        int n,m,now=0;
        memset(sum,0,sizeof(sum));
        memset(num,0,sizeof(num));
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++) scanf("%d",&a[i][j]);
        for(int i=1;i<=n;i++){
            int x=i,y=1;
            ++now;
            while(true){
                sum[now]++;
                if(a[x][y]) num[now]++;
                x--,y++;
                if(x<1||y>m) break;
            }
        }
        for(int i=2;i<=m;i++){
            int x=n,y=i;
            ++now;
            while(true){
                sum[now]++;
                if(a[x][y]) num[now]++;
                x--,y++;
                if(x<1||y>m) break;
            }
        }
        int ans=0;
//        printf("now=%d\n",now);
        for(int i=1;i<=now/2;i++){
            ans+=min(num[i]+num[now-i+1],sum[i]+sum[now-i+1]-num[i]-num[now-i+1]);
//            printf("i=%d ans=%d\n",i,ans);
        }
        printf("%d\n",ans);
    }
}

D. Two Divisors

這個不是很難,仔細分析吧。

#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
#define inf64 0x3f3f3f3f3f3f3f3f
#define debug(x) printf("debug:%s=%d\n",#x,x);
//#define debug(x) cout << #x << ": " << x << endl
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn =4e3;
int phi[maxn],pri[maxn],cnt,v[maxn];
void init() {
    cnt = 0;
    phi[1] = 1;
    memset(v,0,sizeof(v));
    for (int i = 2; i < maxn; ++i) {
        if (!v[i]) {
            v[i] = i;
            pri[cnt++] = i;
        }
        for (int j = 0; j < cnt; ++j) {
            if (1ll * i * pri[j] >= maxn) break;
            v[i * pri[j]] = pri[j];
        }
    }
}
int a[500005],ans1[500005],ans2[500005];
int gcd(int x,int y){
    return y==0?x:gcd(y,x%y);
}
int main(){
    int n;
    init();
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        int x,f=0;
        scanf("%d",&x);
        int y=x;
        for(int j=0;j<cnt;j++){
            while(x%pri[j]==0){
                f = pri[j];
                x/=pri[j];
            }
            if(f) break;
        }
        if(!f) f=x,x=1;
        ans1[i]=x,ans2[i]=f;
        if(ans1[i]==1||ans2[i]==1||gcd(ans1[i]+ans2[i],x)!=1) ans1[i]=ans2[i]=-1;
    }
    for(int i=1;i<=n;i++) printf("%d ",ans1[i]);
    printf("\n");
    for(int i=1;i<=n;i++) printf("%d ",ans2[i]);
    printf("\n");
}

E. Two Arrays

這個你首先要判斷有沒有方案,如果有方案則求出每一個區間的最小區間,然後用組合數求解。

#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
#define inf64 0x3f3f3f3f3f3f3f3f
#define debug(x) printf("debug:%s=%d\n",#x,x);
//#define debug(x) cout << #x << ": " << x << endl
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn =2e5+10;
const int mod = 998244353;
int l[maxn],r[maxn];
int a[maxn],b[maxn];
struct node{
    int v,id;
    node(int v=0,int id=0):v(v),id(id){}
    bool operator<(const node & a)const {
        return a.v<v;
    }
};
priority_queue<node>que;
map<int,int>mp;
int main(){
    int n,m,f=0;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++) scanf("%d",&a[i]),que.push(node(a[i],i));
    for(int i=1;i<=m;i++) scanf("%d",&b[i]);
    b[m+1]=inf;
    for(int i=1;i<=m;i++){
        while(!que.empty()){
            node u = que.top();
//            printf("u.v=%d\n",u.v);
            if(u.v<b[i+1]) r[i]=max(r[i],u.id),que.pop();
            else break;
        }
        if(!r[i]) f=1;
    }
    for(int i=1;i<=n;i++){
        if(a[i]<b[1]) f = 1;
        mp[a[i]]=i;
    }
//    debug(f);
    for(int i=1;i<=m;i++) {
        l[i]=mp[b[i]];
        if(!l[i]) f = 1;
        if(l[i]>r[i]) f = 1;
        if(l[i]<=r[i-1]) f = 1;
    }
    l[1]=1;
    if(f) printf("0\n");
    else{
        ll ans = 1;
        for(int i=2;i<=m;i++){
            ll res = l[i]-r[i-1];
            ans=res*ans%mod;
        }
        printf("%lld\n",ans);
    }
    return 0;
}