Codeforces Round #560 Div. 3


題目鏈接;戳我

於是。。。風潯凌弱菜又去寫了一場div.3

總的來說,真的是比較簡單.......就是.......不開long long見祖宗

貼上題解——

A

給定一個數,為01串,每次可以翻轉一個位置上的數,問最少幾步可以使得它模\(10^x\)\(10^y\)

從后往前貪心即可。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<vector>
#include<map>
#define MAXN 200010
int n,m1,m2,ans;
int a[MAXN];
using namespace std;
int main()
{
    #ifndef ONLINE_JUDGE
    freopen("ce.in","r",stdin);
    #endif
    scanf("%d%d%d",&n,&m1,&m2);
    int i,j;
    for(i=1;i<=n;i++) 
    {
        scanf("%1d",&a[i]);
    }
    for(i=n,j=1;i>=1&&j<=m1;i--,j++)
    {
        if(a[i]==1)
        {
            if(j!=m2+1) ans++;
        }
        else
        {
            if(j==m2+1) ans++;
        }
    }
    cout<<ans<<endl;
    return 0;
}

B

第i天要寫i道題,一些題單,每天可以選擇一個還沒有寫過的題單來寫,上面的題數必須大於等於i,無論一天寫完這個題單還是沒有這個題單都算做過了,以后不能再用。如果不存在這樣一個題單,終止。問最多寫幾天。

排序,然后遍歷一遍即可。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<vector>
#include<map>
#define MAXN 200010
int n,m1,m2,ans;
int a[MAXN];
using namespace std;
int main()
{
    #ifndef ONLINE_JUDGE
    freopen("ce.in","r",stdin);
    #endif
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    sort(&a[1],&a[n+1]);
    int k=1;
    for(int i=1;i<=n;i++)
    {
        if(a[i]<k) continue;
        ans++,k++;
    }
    cout<<ans<<endl;
    return 0;
}

C

給你一個字符串,要求刪去盡量少的一些字符,使得刪完后這個字符串長度為偶數+每個奇數位和它后面的那個偶數位(如果沒有就算了)字符不一樣。

考慮如果從前往后刪,每次如果i和i+1相同,我們不要其中一個,這樣的話不僅這個相同的問題解決了,后面的可能因為整體前移一位也消除了一部分的問題,每次操作的效益明顯高一些。

update:原先那個代碼FST了......原因是剛開始判斷如果合法的話直接輸出了,沒有判斷是否長度為偶數......現在已經更新了AC代碼。QAQ

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<vector>
#include<map>
#define MAXN 200010
int n,m1,m2,ans,nn;
char a[MAXN],tmp[MAXN];
using namespace std;
inline bool check()
{
    if(nn<=1) return true;
    for(int i=1;i<nn;i+=2)
    {
        if(a[i]==a[i+1]) return false;
    }
    return true;
}
inline void solve()
{
    int cnt=0;
    int flag=0;
    for(int i=1;i<=nn;i++,flag^=1)
    {
        if(i!=nn&&flag==0)
        {
            if(a[i]==a[i+1]) 
            {
                ans++;
                flag^=1;
                continue;
            }
        }
        tmp[++cnt]=a[i];
    }
    nn=cnt;
    for(int i=1;i<=nn;i++) a[i]=tmp[i];
    // printf("nn=%d\n",nn);
}
int main()
{
    #ifndef ONLINE_JUDGE
    freopen("ce.in","r",stdin);
    #endif
    scanf("%d",&n);
    scanf("%s",a+1);
    nn=n;
    if(check()&&nn%2==0)
    {
        cout<<0<<endl;
        for(int i=1;i<=n;i++) cout<<a[i];
        cout<<endl;
        return 0;
    }
    while(check()==false)
    {
        solve();
    }
    if(nn&1) ans++,nn--;
    cout<<ans<<endl;
    for(int i=1;i<=nn;i++) cout<<a[i];
    cout<<endl;
    return 0;
}

D

給定一些數,這些數是x的除了1和x的所有約數。求最小的x。如果沒有一個合法的x,輸出-1。
顯然如果數據合法,這些約數里面最小的乘最大的就是這個x,因為最小的那個肯定是x的最小素因子,而最大的那個是x/最小素因子。
計算一下x的約數個數(因為n一共不超過300,所以如果約數個數超過300就不存在這個合法x了,直接終止就行),看看是否和n+2一樣
再遍歷一遍看看每個數是不是x的約數就行了.......

嚶嚶嚶 忘乘1LL死的好慘

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<vector>
#include<map>
#define MAXN 200010
int n,m1,m2,ans,nn,t;
int a[MAXN];
using namespace std;
inline int calc(long long x)
{
    int cur_ans=0;
    for(int i=2;1ll*i*i<=x;i++)
    {
        if(x%i==0) cur_ans+=2;
        if(1ll*i*i==x) cur_ans--;
        if(cur_ans>n) return 0x3f3f3f3f;
    }
    return cur_ans;
}
inline bool check(long long x)
{
    for(int i=1;i<=n;i++)
        if(x%a[i])
            return false;
    return true;
}
int main()
{
    #ifndef ONLINE_JUDGE
    freopen("ce.in","r",stdin);
    #endif
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%d",&a[i]);
        sort(&a[1],&a[n+1]);
        long long now=1ll*a[1]*a[n];
        int sum=calc(now);
        if(n!=sum||check(now)==false) printf("-1\n");
        else printf("%lld\n",now);
    }
    return 0;
}

E

給定序列A,B。可以對B重排,使得\(\sum_{1\le l \le r \le n}\sum_{l\le i \le r}a_ib_i\)最小

啊。。。對每個a的位置加權上它的覆蓋次數,然后排個序。a最小乘b最大即可。
覆蓋次數就是\(i*(n-i+1)\)

嚶嚶嚶 忘開long long死的好慘

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#define MAXN 200010
#define mod 998244353
using namespace std;
int n;
int b[MAXN];
long long ans=0;
struct Node{long long cnt;int sum;}a[MAXN];
inline bool cmp(struct Node x,struct Node y)
{
    if(1ll*x.sum*x.cnt>1ll*y.sum*y.cnt) return 1;
    else return 0;
}
int main()
{
    #ifndef ONLINE_JUDGE
    freopen("ce.in","r",stdin);
    #endif
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%d",&a[i].sum),a[i].cnt=1ll*i*(n-i+1);
    // for(int i=1;i<=n;i++) printf("%d\n",a[i].cnt);
    for(int i=1;i<=n;i++) scanf("%d",&b[i]);
    sort(&a[1],&a[n+1],cmp);
    sort(&b[1],&b[n+1]);
    for(int i=1;i<=n;i++)
        ans=(ans+1ll*a[i].sum*a[i].cnt%mod*b[i]%mod)%mod;
    cout<<ans<<endl;
    return 0;
}

F1&&F2

n個物品 m次打折活動 一次打折活動(di,ti)表示物品ti在第di天打折,打折的話需要1元購買,不打折的話2元。
給定每種物品需要買的數量。每一天都會多一塊錢,問最短多少天買夠需要的所有東西。
(每次購買只要有錢 不限制數量 不限制種類)

顯然對於一個物品,在后面選比在前面選優。二分選擇的天數+貪心即可。

#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<vector>
#define MAXN 400010
using namespace std;
int n,m,tot;
int need[MAXN],tmp[MAXN],last[MAXN];
vector<int>vec[MAXN];
inline bool check(int x)
{
    memset(last,0,sizeof(last));
    memcpy(tmp,need,sizeof(need));
    for(int i=1;i<=x;i++)
    {
        for(int j=0;j<vec[i].size();j++)
        {
            int now=vec[i][j];
            last[now]=i;
        }
    }
    int money=0,cur_ans=0;
    for(int i=1;i<=x;i++)
    {
        money++;
        for(int j=0;j<vec[i].size();j++)
        {
            int now=vec[i][j];
            while(last[now]==i&&money&&tmp[now])
                tmp[now]--,cur_ans++,money--;
        }
    }
    cur_ans+=money/2;
    if(cur_ans>=tot) return true;
    else return false;
}
int main()
{
    #ifndef ONLINE_JUDGE
    freopen("ce.in","r",stdin);
    #endif
    scanf("%d%d",&n,&m);
    int l=0,r=0,ans;
    for(int i=1;i<=n;i++) scanf("%d",&need[i]),tot+=need[i];
    for(int i=1;i<=m;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        vec[x].push_back(y);
    }
    r=tot*2;
    while(l<=r)
    {
        int mid=(l+r)>>1;
        if(check(mid)) ans=mid,r=mid-1;
        else l=mid+1;
    }
    printf("%d\n",ans);
    return 0;
}

大括號換行!正義!!
同義句壓行!正義!!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM