19 LatterMay CodeForce 1165Div.3(6Pro)

前言

地址:https://vjudge.net/contest/302045#overview

如果是英文劝退……那打扰了,我英语也不行,但英语字典是能带的。有电脑,就用网翻单词然后理解也是可以的吧。
以下是基于对题目的理解,简单提炼的题意,具体数据范围还是要自己看,看完中文题意,会发现还是有一些比较简单的。
至于代码和思路之后再说。

1165A

题意

你被给予了一个n位的十进制数字,没有前导0,每位数字只有0或者1。

你可以对这个数字进行一些操作,对于每个操作,可以将0变成1,或者1变成0,在进行一定的操作后,你可能获得一个前导位0的数字,但这个无关紧要。

现在,你被基于两个整数 0<=y<x<n,你的任务是计算应该执行的最小操作数,使这个数字变成对10^x 取模后,余数为 10^y 的数 ,换句话说,最终获得的数字应该满足 %10^x = 10^y

第一行输入十进制数的位数,x和y
第二行输入十进制数字,左边最高阶

输出最少的操作数

思路

因为只关注对10x取模为10y次方,那么我们只关注,怎么只操作n位数字的后x位,除了对倒数第y+1位要置1外,其他都置为0。我们将后y位数字里面为1的数量记录为time,如果要置1的位置的数字为0则操作数time+1,如果要置1的位置的数字位1,则重复操作,输出time-1.

源代码

#include <iostream>
using namespace std;
char s[200010];
int n,x,y,cunt;
int main()
{
    cin>>n>>y>>x;
    cin>>s;
    cunt=0;
    for (int i=n-y;i<n;i++)
        if (s[i]!='0') cunt++;
    if (s[n-x-1]=='0') cunt++;
    else cunt--;
    cout<<cunt<<endl;
    return 0;
}

1165B

题意

现在有n场比赛的题目,并分别有ai个题目,
主人公每天选择其中一场比赛来做,对于第k天,主人公会去AC比赛里面的k道题目,然后就不做了。
如果第k天选择的这场比赛题目少于k题,那么主人公就不参加了。
请问主人公最多能参加几场比赛。

思路

这题有两个方法,看到另一个同学的方法,感觉我的有些愚钝。
第一种,则是小到大排序,然后遍历数组,每遇到能满足做题数量的比赛,则天数加一。
第二种,则是用数组来记录有n道题的比赛数量,然后遍历一次数组,算是基数排序吧。

源代码,第一种

#include <cstdio>
#include <algorithm>
using namespace std;
int a[200010],n,q;
int main()
{
    scanf("%d",&n);
    for (int i=0;i<n;i++)
        scanf("%d",a+i);
    sort(a,a+n);
    for (int i=0;i<n;i++)
        if (a[i]>q) q++;
    printf("%d\n",q);
    return 0;
}

源代码,第二种

#include <stdio.h>
#include <string.h>
int main()
{
    int n, a[200005] = {0}, i, j, t, count = 0;
    scanf("%d", &n);
    for(i = 0; i < n; i++)
    {
        scanf("%d", &t);
        a[t]++;
    }
    for(i = 1, j = i; i <= n; i++)
    {
        if(j < i)j = i;
        while(0 == a[j] && j <= 200003)j++;
        if(j > 200003)break;
        count++;
        a[j]--;
    }
    printf("%d\n", count);
    
    return 0;
} 

1165C

题意

如果一个字符串的长度是偶数,并且所有在奇数位置的字符和它的下一位的字符不是相同的,那么这个字符串是好字符串。
现在给你一个字符串s,请问最少要删除几个字符才能将它变成好字符串,请将删除的个数k和删除后的字符串输出,如果为空则换行。

思路

这题的方法比较贪心,我们知道像abccd这种字符串,我们只需要删一个就能变成一个好字符串。可以是ab之一,也可以是c。对于连续的重复的字符串,只要它符合好字符串的规则,也就是前一个在偶数位置,后一个在奇数位置,那么就不需要特别处理。当然多与两个便一定要删减了。
我们可以采取贪心的策略,重新组合一个字符串。当我们取奇数位置时,可以随意取,取偶数位置时候,如果和奇数位置相同,则不取。

源代码

#include <cstdio>
char s[200010],res[200010];
int n,len,i;
int main()
{
    scanf("%d%s",&n,s);
    res[0]=s[0];
    for (i=1,len=1;i<n;i++)
        if (s[i]!=s[i-1] || !(len&1) )
            res[len++]=s[i];
    if (len & 1)
        res[--len]=0;
    printf("%d\n%s\n",n-len,res);
    return 0;
}

1165D

题意

我们猜测有这么一个数字x,你被给予了几乎所有这个数字的除数,这个几乎的意思是,除了1和x以外,x的所有因子都已经被给予了,并且我们保证,输入的每一个数字都是不同的,如果这个输入不符合要求,或者找不到这样的数,那么输出-1。

思路

这题主要是问你,如何通过这些数字。
得到X,求有没有重复数字,是否都属于它的因子,有没有漏的因子
分析步骤:
排序
如果数组符合要求,那么这个X必定是最大最小值相乘可得
如果出现1那么必定不符合要求
说了没有重复,有重复当然不符合
只要它符合X,那么一定有n/2组数相乘的结果为X
如果以上都符合,那么我分解质因数,计算所有不同因子的数量cnt,去掉1和X为cnt-2

源代码

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
using namespace std;
long long n,t,a[310];
long long ans()
{
    cin>>n;
    long long cnt=1,sum,q;
    for (int i=0;i<n;i++)
        cin>>a[i];
    sort(a,a+n);
    sum=a[0]*a[n-1];
    q=sum;
    //如果数组符合要求,那么这个X必定是最大最小值相乘可得
    if (a[0]==1) return -1;
    //如果出现1那么必定不符合要求
    for (int i=1;i<n;i++)
        if (a[i]==a[i-1]) return -1;
    //说了没有重复,有重复当然不符合
    for (int i=1,j=n-2;i<=j;i++,j--)
        if (a[i]*a[j] != sum) return -1;
    //只要它符合X,那么一定有n/2组数相乘的结果为X
    for (int i=2,k=0;i*i<=q;i++)
        if (q%i==0) {
            k=2;
            q/=i;
            while (q%i==0)
            {
                k++;
                q/=i;
            }
            cnt*=k;
        }
    if (q>1) cnt*=2;
    //如果以上都符合,那么我分解质因数,计算所有不同因子的数量,去掉1和X为cnt-2
    if (cnt-2 != n) return -1;
    return sum;
}
int main()
{
    cin>>t;
    while (t--)
        cout<<ans()<<endl;
    return 0;
}

1165E

题意

你被给予了两个数组,分别是a和b,它们的长度都为n,我们定义f(l,r)的值为,对所有满足(l<=i<=r)的情况下的ai*bi求和。
对满足(l<=r)的所有情况下f(l,r)的求和,
你可以随意移动数组b里面的数字的位置,然后用求和的结果对998244353取模。
请输出求和得到的最小结果对998244353取模后的值(不是求余数最小,而是结果最小)

思路

我们知道,对于两个元素数量相同的数组,如何排序让它们的各位相乘求和的值最小,那么只能是一个数组正序,一个数组倒序,然后逐个相乘求和。
对于这题,a和b只能移动b数组的顺序,那么其实是一样的,只要b第i大的数字对应a第i小的数字就行了。
但是题目给出了f(l,r)这个函数,并且是所有这个函数相加。不难得到,在n个元素的数组种,对于第i个元素,必定有i*(n-i+1)个区间将这个元素包含在内,也就是说,和第i个元素相关的乘积将出现以上次累加。
对于a这个数组来说,它是不能动的,何不先把这些累计的次数与a里的元素相乘呢。
我们将a内元素和对应累计次数相乘得到的新数组c排正序,b排倒序,再逐位相乘相加,取个模,那就是我们要求的答案了。

源代码

#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
#define MOD 998244353
ll a[200010],b[200010],n,ans,k,q[200010];
int cmp(ll x,ll y) {
    return a[x]>a[y];
}
int main()
{
    cin>>n;
    for (int i=0;i<n;i++)
    {
        cin>>a[i];
        a[i]*=(i+1)*(n-i);
        q[i]=i;
    }
    for (int i=0;i<n;i++)
        cin>>b[i];
    sort(q,q+n,cmp);
    sort(b,b+n);
    ans=0;
    for (int i=0;i<n;i++)
    {
        k=(a[q[i]]%MOD*b[i])%MOD;
        ans=(ans+k)%MOD;
    }
    cout<<ans<<endl;
    return 0;
}

1165F(easy version)

题意

简单版和难版题目的区别只在于数据范围。
主人公Ivan,玩一个电脑游戏,包括很多微交易,可以得到让角色变得更帅的饰品,他想自己的角色看起来更酷,他想利用这些微交易得到饰品,并且他在得到所有东西后才开始玩这个游戏。
每一天早上,Ivan可以赚到游戏里一单位的burle(游戏货币)
有n种微交易,对于每一种微交易的花费,打折时每个饰品花费1单位burle,平时则花费2单位burle。对于第i个饰品,他想要进行ki次交易,订单将在晚上完成。
游戏商店有m次折扣,第j次输入(dj,tj)代表第t种商品在第d天打折。
Ivan想要尽早得到所有的物品,你的任务是计算最少经过多少时间他能买到所有想要数量的饰品,并开始游戏。
……………………有人说还是不懂我简单说下
主角想买一些东西,然后从第一天开始每天领一块钱
平时每件东西是两块,打折日对某些种类当天就一块。
给了你打折日,还有他想买的东西,给好种类和数量了
打折日也说明了日期和种类了
问你最短多少时间内能买完这些东西

思路

对于结果来说,最重要的是天数。如果主角想要n个物品,那么所需要天数必定在n~2n以内,我们只需要找到其中最小的可以买完东西的天数就行了。
对于固定的天数day,我们能接触到的打折活动必定在第day天及之前能接触到。那么对于同一件物品,打折的时间越后,能一次性买的数量越多。我们不妨在这天尽量买足所需数量。但是请注意,在第day天前举办的打折活动,并不能使用day个货币,也就是无法超前消费,那么,对于第day天剩余拥有的货币bday,和第fday天举办的活动(fday<day),我们只能用其中fday个货币,而,bday-fday个货币必定只能用来买2货币一个的物品。
同理,对于第5天和第3天的打折,假设第五天有五个货币,为了满足需求,我买了三个,那么对于第三天的打折,我最多只能买两个,假设对这天打折的需求也是三个,那么剩余一个必定要通过两元一个的原价购买。所以这样的贪心并不影响结果。

源代码

#include <iostream>
#include <algorithm>
using namespace std;
#define maxn 200010
//该算法对于两个范围难度的题都能解决。
int lf, rt, b[maxn];
int ned[maxn], da[maxn], tp[maxn];
int k, p[maxn], n, m;
int cmp(int x, int y) {
    return da[x] < da[y];
}
int min(int a, int b) {
    return a < b ? a : b;
}
bool check(int v) {//测试v块钱能否买完
    for (int i = 1; i <= n; i++)
        b[i] = 1;
    //经过最后打折日的物品在前面打折日则不再购买,因为必定买完,或者剩下的需求没法满足
    int mon = v, cost = 0;
    for (int i = m; i > 0; i--)
        if (b[tp[p[i]]] && da[p[i]] <= v) {
            b[tp[p[i]]] = 0;
            mon = min(mon, da[p[i]]);
            cost += min(mon, ned[tp[p[i]]]);
            mon -= min(mon, ned[tp[p[i]]]);;
        } //只要低于v的折扣都能接触到,但能买的最大数量限制于打折时间和需求。
    return cost + (v - cost) / 2 >= lf;
}
int divide(int lf, int rf) {
    int mid;
    while (lf < rf) {
        mid = (lf + rf) / 2;
        if (check(mid)) rf = mid - 1;
        else lf = mid + 1;
    }
    //为了优化贪心找到答案的次数,我使用二分法。
    return check(rf) ? rf : rf+1;
    //因为退出循环时存在rf=lf和rf=lf-1的可能
}
int main()
{
    cin >> n >> m;
    lf=0;
    for (int i = 1; i <= n; i++){
        cin >> ned[i];
        lf += ned[i];
    } rt = lf * 2;
    for (int i = 1; i <= m; i++) {
        cin >> da[i] >> tp[i];
        p[i] = i;
    }
    sort(p + 1, p + 1 + m, cmp);
    cout << divide(lf, rt) << endl;
    return 0;
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,163评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,301评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,089评论 0 352
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,093评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,110评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,079评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,005评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,840评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,278评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,497评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,667评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,394评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,980评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,628评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,796评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,649评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,548评论 2 352