1. 程式人生 > 實用技巧 >Codeforces Round #549題解

Codeforces Round #549題解

A題

計算每組最後出現的那個取min

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pll;
typedef pair<int,int> plll;
const int N=2e6+10;
const int inf=0x3f3f3f3f;
int a[N];
int main(){
    ios::sync_with_stdio(false);
    int n;
    cin>>n;
    int i;
    
for(i=1;i<=n;i++){ cin>>a[i]; } int cnt1=0,cnt2=0; for(i=1;i<=n;i++){ if(a[i]==1) cnt1=i; else cnt2=i; } cout<<min(cnt1,cnt2)<<endl; return 0; }
View Code

B題

這題有數位dp控制最高位那味,如果最高位不受限

那麼後面全取9,因此對每一位都做一下這個判斷即可

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pll;
typedef pair<int,int> plll;
const int N=2e6+10;
const int inf=0x3f3f3f3f;
int a[N];
ll pre[N];
int main(){
    ios::sync_with_stdio(false);
    ll n;
    int i,j;
    cin>>n;
    int
cnt=0; while(n){ a[++cnt]=n%10; n/=10; } if(cnt==1){ cout<<a[1]<<endl; return 0; } pre[0]=1; for(i=1;i<=20;i++){ pre[i]=pre[i-1]*9; } reverse(a+1,a+1+cnt); ll ans=1; ll mx=1; for(i=1;i<=cnt;i++){ ans=ans*a[i]; } for(i=1;i<=cnt;i++){ ll tmp=a[i]-1; if(a[i]==1){ tmp=1; } for(j=1;j<i;j++){ tmp*=a[j]; } for(j=i+1;j<=cnt;j++) tmp*=9; ans=max(ans,tmp); } cout<<ans<<endl; return 0; }
View Code

C題

過於水,記錄三個陣列判斷一下就行

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pll;
typedef pair<int,int> plll;
const int N=2e6+10;
const int inf=0x3f3f3f3f;
int h[N],ne[N],e[N],idx;
int in[N],num[N];
int vis[N];
void add(int a,int b){
}
int main(){
    ios::sync_with_stdio(false);
    int n;
    cin>>n;
    int i;
    for(i=1;i<=n;i++){
        int a,b;
        cin>>a>>b;
        if(a==-1){
            continue;
        }
        in[a]++;
        vis[i]=b;
        num[a]+=b;
    }
    int flag=0;
    for(i=1;i<=n;i++){
        if(vis[i]&&(in[i]==num[i])){
            cout<<i<<" ";
            flag=1;
        }
    }
    if(!flag){
        cout<<-1;
    }
    cout<<endl;
    return 0;
}
View Code

D題

起點在哪其實無所謂,那麼我們假定0點為對於起點最近的那個,這樣就有兩種情況,一種是起點後a,一種是起點前a,那麼對於b也是兩種情況,不同的是,b可以是每個點的前後差值,因此列舉每種情況取最值即可

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pll;
typedef pair<int,int> plll;
const int N=2e6+10;
const int inf=0x3f3f3f3f;
ll gcd(ll a,ll b){
    return b?gcd(b,a%b):a;
}
int main(){
    ios::sync_with_stdio(false);
    ll n,k;
    ll a,b;
    cin>>n>>k>>a>>b;
    ll ans=0;
    ll res=1e18;
    ll tmpa=a;
    ll i;
    for(i=0;i<=(n-1)*k;i+=k){
        ll tmpb=(i-b+n*k)%(n*k);
        ll d=(tmpb-tmpa+n*k)%(n*k);
        ans=max(ans,n*k/gcd(d,n*k));
        res=min(res,n*k/gcd(d,n*k));
        tmpb=(i+b+n*k)%(n*k);
        d=(tmpb-tmpa+n*k)%(n*k);
        ans=max(ans,n*k/gcd(d,n*k));
        res=min(res,n*k/gcd(d,n*k));
    }
    tmpa=(-a+n*k)%(n*k);
    for(i=0;i<=(n-1)*k;i+=k){
        ll tmpb=(i-b+n*k)%(n*k);
        ll d=(tmpb-tmpa+n*k)%(n*k);
        ans=max(ans,n*k/gcd(d,n*k));
        res=min(res,n*k/gcd(d,n*k));
        tmpb=(i+b+n*k)%(n*k);
        d=(tmpb-tmpa+n*k)%(n*k);
        ans=max(ans,n*k/gcd(d,n*k));
        res=min(res,n*k/gcd(d,n*k));
    }
    cout<<res<<" "<<ans<<endl;
    return 0;
}
View Code