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;
}