zcmu-新生宝贝们的第五次试水题解

A - Ehab and another construction problem

【题解】

题意么就是寻找一对a,b满足

第二条的意思就是b整除a,a%b==0

已经有的同学发现了,a=b=x的时候是符合题意的,但是还要考虑一种情况就是x=1的时候,a*b=x,a/b=x,不符合。

【代码】

#include<stdio.h>
int main()
{
	int x;
	scanf("%d",&x);
	if(x==1) printf("-1");
	else printf("%d %d",x,x);
} 

一看么数据就100,直接暴力跑也行。

【代码】

#include<stdio.h>
int main()
{
    int x; scanf("%d",&x);
    for(int i=1;i<=x;i++)
        for(int j=i;j<=x;j+=i)
        {
            if(i*j>x&&j/i<x)
            {
                printf("%d %d\n",j,i);
                goto out; //跳到out
            }
        }
    puts("-1");
    out:;
    return 0;
}

B - Ehab and subtraction

 【题解】

题意么就是给定一个长度为n的序列,然后做k次操作,每次操作么选择非0最小值让剩下所有非0的数减去最小值,并输出这个最小值,如果剩下都是0么就输出0.

如果直接每次循环寻找最小值再遍历减去最小值的话是会超时的,这里做个小优化,定义一个变量存储需要减去的最小值之和,每次做判断即可。

【代码】

#include<stdio.h>
#include <algorithm>
using namespace std;
int main()
{
    int n,k,a[100005];
    scanf("%d%d",&n,&k);
    for(int i=0;i<n;i++) scanf("%d",&a[i]);
    sort(a,a+n);
    int cut=0,c=0;
    while(k--)
    {
        while(a[c]-cut<=0&&c<n) c++;
        if(c==n) break;
        printf("%d\n",a[c]-cut);
        cut+=a[c]-cut;
    }
    for(int i=0;i<=k;i++) puts("0");
    return 0;
}

C - Ehab and a 2-operation task

 【题解】

题意么就是给定一个长度为n的序列,要求执行给定操作1或者2不超过n+1次使得序列变成一个上升序列。

操作一加上一个数,操作二取模。通过取模我们可以把一个数变成任意一个不大于它本身的数,因此我们考虑把序列变成类似1,2,3,4,5...这种序列,a[i]∈[0,1e5],为了防止a[i]<i取模不到i,我们可以加上一个比较大的数,然后每个数对a[i]-i取模即得到i。

【代码】

#include<stdio.h>
int main()
{
    int n,a[2010];  scanf("%d",&n);
    for(int i=1;i<=n;++i) scanf("%d",&a[i]);
    printf("%d\n1 %d 500000\n",n+1,n);
    for(int i=1;i<=n;++i) a[i]+=500000;
    for(int i=1;i<=n;++i) printf("2 %d %d\n",i,a[i]-i);
    return 0;
}

D - Lazyland

 【题解】

题意:n个人选择k个工作,第i个人选择工作a[i],并且第i个人有不高兴程度b[i],为了使得每个工作都有人做,需要你去劝说部分的人改变工作意愿,这时候总的不高兴程度就会增加,输出使得每个工作岗位都有人做的总的最低不高兴程度。

考虑一点,我们需要改变多少人呢?记录下不止一个人有意愿的岗位的人数-1,与n-k的差,即需要更改意愿的人数。

首先,按不高兴程度升序排序,然后按顺序取需要更改意愿的人数个不高兴程度并求和输出。

【代码】

#include <stdio.h>
#include <algorithm>
using namespace std;
#define maxn 100000
#define ll long long
struct p{
    int a,b;
}f[maxn+5];
bool cmp(p x,p y)
{
    return x.b<y.b;
}
int main()
{
    int n,k,vis[maxn+5]={0};
    scanf("%d%d",&n,&k);
    int c=0; ll ans=0;
    for(int i=0;i<n;i++)
    {
        scanf("%d",&f[i].a);
        if(vis[f[i].a]) c++;
        vis[f[i].a]++;
    }
    for(int i=0;i<n;i++) scanf("%d",&f[i].b);
    sort(f,f+n,cmp);
    for(int i=0;c!=n-k;i++)
    {
        if(vis[f[i].a]>1) vis[f[i].a]--,c--,ans+=f[i].b;
    }
    printf("%lld\n",ans);
}

E - Many Equal Substrings

【题解】

题意:输出给定长度为n的字符串出现k次的最短字符串。

思路:寻找最长相同前后缀,除第一次的输出外都舍掉前缀再输出即为最短。

【代码】

#include <algorithm>
#include <iostream>
using namespace std;
int main()
{
    int n,k; string a;
    cin>>n>>k; cin>>a;
    int l=n-1;
    string t1=a.substr(0,l);
    string t2=a.substr(n-l,l);
    while(t1!=t2&&l>0)
    {
        l--;
        t1=a.substr(0,l);
        t2=a.substr(n-l,l);
    }
    cout<<a;
    for(int i=1;i<k;i++)
        for(int j=l;j<n;j++)
            cout<<a[j];
    cout<<endl;
    return 0;
}

F - Creating the Contest

【题解】

题意:给定一个升序序列,输出最长连续满足ai<=ai-1*2的子序列长度。

思路:因为给定的是升序序列,问题就变的很简单了。遍历判断符合要求的子序列长度并更新答案即可。

【代码】

#include <stdio.h>
#define N 200000
int main()
{
    int n,ans=0,a[N+5];
	scanf("%d",&n);
	for(int i=1,l=1;i<=n;i++)
    {
		scanf("%d",&a[i]);
		if(a[i-1]*2<a[i]) l=i;
		if(i-l+1>ans) ans=i-l+1;
	}
	printf("%d\n",ans);
}

G - The Marshtomp has seen it all before

 【题解】

字符串的查找替换。

【代码】

#include <string>
#include <iostream>
using namespace std;
int main()
{
    string a;
    while(getline(cin,a))
    {
        int l=a.size();
        for(int i=0;i<l-7;i++)
        {
            string b=a.substr(i,9);
            for(int j=0;j<9;j++)
                if(b[j]>='A'&&b[j]<='Z')
                   b[j]=b[j]-'A'+'a';
            if(b=="marshtomp")
            {
                a=a.replace(a.begin()+i,a.begin()+i+9,"fjxmlhx");
                i+=7;
            }
        }
        cout<<a<<endl;
    }
    return 0;
}

后三题:H I J 题解

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值