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相同,我们不要其中一个,这样的话不仅这个相同的问题解决了,后面的可能因为整体前移一位也消除了一部分的问题,每次操作的效益明显高一些。

#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())
    {
        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;
}

原文地址:https://www.cnblogs.com/fengxunling/p/10867296.html

时间: 2024-08-30 17:01:09

Codeforces Round #560 Div. 3的相关文章

Codeforces Round #560 (Div. 3) B题

题目网址:http://codeforces.com/contest/1165/problem/B 题目大意:给出n个数,问有多少个数满足连续大于等于自然数集中的数,即以此大于等于1,2,3…… 题解:直接sort一下,然后从小到大和1,2,3……比较 1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=2e5+7; 4 int a[maxn]; 5 int main() 6 { 7 int n,tot=1,ans

Codeforces Round #560 (Div. 3) A题

题目网址:http://codeforces.com/contest/1165/problem/A 题目大意:给定一行01串,开头必是1,length为n,可对串进行变化,0变成1,1变成0,问经过最少的变化,该串mod 10^x==10^y.(^是乘方),输出变化次数. 题解:简单分析可知,比如串是1001000,则mod 1000 == 0,mod 10000 == 1000,所以直接在n-x之和判断即可. 1 #include<bits/stdc++.h> 2 #define ll lo

C Good String Codeforces Round #560 (Div. 3)

Let's call (yet again) a string good if its length is even, and every character in odd position of this string is different from the next character (the first character is different from the second, the third is different from the fourth, and so on).

Codeforces Round #428 (Div. 2)

Codeforces Round #428 (Div. 2) A    看懂题目意思就知道做了 #include<bits/stdc++.h> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define rep(i,a,b) for (int i=a; i<=b; ++i) #define per(i,b,a) for (int i=b; i>=a; --i

Codeforces Round #424 (Div. 2) D. Office Keys(dp)

题目链接:Codeforces Round #424 (Div. 2) D. Office Keys 题意: 在一条轴上有n个人,和m个钥匙,门在s位置. 现在每个人走单位距离需要单位时间. 每个钥匙只能被一个人拿. 求全部的人拿到钥匙并且走到门的最短时间. 题解: 显然没有交叉的情况,因为如果交叉的话可能不是最优解. 然后考虑dp[i][j]表示第i个人拿了第j把钥匙,然后 dp[i][j]=max(val(i,j),min(dp[i-1][i-1~j]))   val(i,j)表示第i个人拿

Codeforces Round #424 (Div. 2) C. Jury Marks(乱搞)

题目链接:Codeforces Round #424 (Div. 2) C. Jury Marks 题意: 给你一个有n个数序列,现在让你确定一个x,使得x通过挨着加这个序列的每一个数能出现所有给出的k个数. 问合法的x有多少个.题目保证这k个数完全不同. 题解: 显然,要将这n个数求一下前缀和,并且排一下序,这样,能出现的数就可以表示为x+a,x+b,x+c了. 这里 x+a,x+b,x+c是递增的.这里我把这个序列叫做A序列 然后对于给出的k个数,我们也排一下序,这里我把它叫做B序列,如果我

[Codeforces] Round #352 (Div. 2)

人生不止眼前的狗血,还有远方的狗带 A题B题一如既往的丝帛题 A题题意:询问按照12345678910111213...的顺序排列下去第n(n<=10^3)个数是多少 题解:打表,输出 1 #include<bits/stdc++.h> 2 using namespace std; 3 int dig[10],A[1005]; 4 int main(){ 5 int aa=0; 6 for(int i=1;;i++){ 7 int x=i,dd=0; 8 while(x)dig[++dd

Codeforces Round #273 (Div. 2)

Codeforces Round #273 (Div. 2) 题目链接 A:签到,仅仅要推断总和是不是5的倍数就可以,注意推断0的情况 B:最大值的情况是每一个集合先放1个,剩下都丢到一个集合去,最小值是尽量平均去分 C:假如3种球从小到大是a, b, c,那么假设(a + b) 2 <= c这个比較明显答案就是a + b了.由于c肯定要剩余了,假设(a + b)2 > c的话,就肯定能构造出最优的(a + b + c) / 3,由于肯定能够先拿a和b去消除c,而且控制a和b成2倍关系或者消除

Codeforces Round #339 (Div. 2) B. Gena&#39;s Code

B. Gena's Code It's the year 4527 and the tanks game that we all know and love still exists. There also exists Great Gena's code, written in 2016. The problem this code solves is: given the number of tanks that go into the battle from each country, f