Codeforces Round #501 (Div. 3)前4题题解

A. Points in Segments

![这里写图片描述](https://img-blog.csdn.net/20180801005148131?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3N1eHV5dTAx/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)

Examples
input
3 5
2 2
1 2
5 5
output
2
3 4
input
1 7
1 7
output
0

直接暴力模拟,O(n^2)

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <queue>
#include <cstdlib>
#define For(i,l,r) for(int i=l;i<=r;++i)
using namespace std;
int n,m;
bool line[101];
int main()
{

	queue<int> ans;
	int tx,ty;
	scanf("%d %d",&n,&m);
	For(i,1,n)
	{
		scanf("%d %d",&tx,&ty);
		For(j,tx,ty)
		 line[j]=1;
	}
	For(i,1,m)
	 if(!line[i])
	 	ans.push(i);
	cout<<ans.size()<<"\n";
	while(!ans.empty())
	{
		cout<<ans.front()<<" ";
		ans.pop();
	}
	return 0;
}

B. Obtaining the String

![这里写图片描述](https://img-blog.csdn.net/20180801005421169?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3N1eHV5dTAx/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70) Examples input 6 abcdef abdfec

output
4
3 5 4 5

input
4
abcd
accd

output
-1

不要求步数最小就比较好办了(一开始只看到minimize还以为是个dp之类的,回头才看到do not have to,还是要多审审题啊。。。)
把t中的字符和s中的一个个匹配,按t中的序号给s中的赋值,做成一个数列
然后冒泡排序即可
依然是O(n^2) 。。。
这题一开始想的差不多,但没想转成序号的数列之后再冒泡排序,直接用字母一个一个比对,所以耽误了很长时间。。。
所以说,Think Twice , Code Once ,这句话我执行的还是不够彻底

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>
#include <cstdlib>
#define For(i,l,r) for(int i=l;i<=r;++i)

using namespace std;
int n,scnt[27],tcnt[27],sd[60],td[60];
char s[60],t[60];
int main()
{
	queue<int> ans;
	scanf("%d",&n);
	For(i,1,n)
	{
		while((s[i]=getchar())==' '||s[i]=='\n'||s[i]=='\r');
		scnt[s[i]-'a'+1]++;
	}
	For(i,1,n)
	{
		while((t[i]=getchar())==' '||t[i]=='\n'||t[i]=='\r');
		tcnt[t[i]-'a'+1]++;
	}
	For(i,1,26)
	{
		if(scnt[i]!=tcnt[i])
		{
			cout<<"-1";
			return 0;
		}
	}
	For(i,1,n)
	{
		td[i]=i;
		For(j,1,n)
		{
			if(s[j]==t[i]&&!sd[j])
			{
				sd[j]=i;
				break;
			}
		}
	}
	For(i,1,n)
	{
		For(j,1,n-1)
		{
			if(sd[j]>sd[j+1])
			{
				ans.push(j);
				swap(sd[j],sd[j+1]);
			}
		}
	}
	cout<<ans.size()<<'\n';
	while(!ans.empty())
	{
		cout<<ans.front()<<" ";
		ans.pop();
	}
}

C. Songs Compression

![这里写图片描述](https://img-blog.csdn.net/20180801005922576?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3N1eHV5dTAx/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70) Examples input 4 21 10 8 7 4 3 1 5 4

output
2

input
4 16
10 8
7 4
3 1
5 4

output
-1

分情况,先特判不可能全部装下和不需要压缩以及全部压缩(也不一定,可能有压缩前和压缩后占用空间相等的,这也是个小细节,这里所说的全部压缩是指粗略的全部压缩)之后恰好能装下的情况
如果不属于以上三种情况,那就按压缩前和压缩后的占用空间的差值排序,然后贪心就行了

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>

#define For(i,l,r) for(int i=l;i<=r;++i)
#define MAXN 100001
using namespace std;
long long as,bs;
int n,m,song[MAXN];
bool cmp(int a,int b)
{
	return a>b;
}
int main()
{
	int tx,ty,tn;
	scanf("%d %d",&n,&m);
	tn=n;
	For(i,1,n)
	{
		scanf("%d %d",&tx,&ty);
		if(tx==ty)
			--tn;
		song[i]=tx-ty;
		as+=tx;
		bs+=ty;
	}
	if(as<=m)//无需压缩
	{
		cout<<"0";
		return 0;
	}
	if(bs>m)//不可能全装下
	{
		cout<<"-1";
		return 0;
	}
	if(bs==m)//全压缩恰好全装下
	{
		cout<<tn;
		return 0;
	}
	sort(song+1,song+n+1,cmp);
	bs=0;//使用bs记录答案
	For(i,1,n)
	{
		bs++;
		as-=song[i];
		if(as<=m)
		 break;
	}
	cout<<bs;
	return 0;
}

D. Walking Between Houses

![这里写图片描述](https://img-blog.csdn.net/20180801010541998?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3N1eHV5dTAx/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)

Examples
input
10 2 15

output
YES
10 4

input
10 9 45

output
YES
10 1 10 1 2 1 2 1 6

input
10 9 81

output
YES
10 1 10 1 10 1 10 1 10

input
10 9 82

output
NO

开始做这题的时候还剩25分钟左右
真的感觉A不掉了
结果最后10s交上然后A了23333
这题也算一个贪心吧
首先有两种情况是不能实现的

1.剩余(就是从第一步开始,但是这样说概括比较广泛)的平均每步要走的距离>(n-1)
2.s<k,即平均每步要走的距离不到1

特判这两种情况输出"NO"
否则就输出"YES"
然后就是怎么走的问题了
(突然感觉CF的评测机制很优秀啊,没有限定什么字典序最小之类的,但是长此以往怕是NOIp要爆零啊。。。)
每步走剩下步数每步平均要走的距离上取整
具体每一步怎么走呢
我们肯定是希望当前位置可以到达的距离远一些,不希望当前位置居中
那我们就先判断在左半区间还是右半区间,优先向靠边的方向走
然后就是判断能不能走了,一直这样循环即可

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>

#define For(i,l,r) for(int i=l;i<=r;++i)

using namespace std;
int n,k;
long long s;
int main()
{
	long long temp;
	cin>>n>>k>>s;
	temp=ceil((double)(s/(double)k));
	if(temp>n-1||s<k)
	{
		cout<<"NO";
		return 0;
	}
	cout<<"YES\n";
	int now=1;
	For(i,1,k)
	{
		temp=ceil((double)(s/(double)(k-i+1)));
		//cout<<temp<<'a'<<'\n';
		s-=temp;
		if(now<=n/2&&now-temp>0)
		{
			now-=temp;
			cout<<now<<" ";
			continue;
		}
		if(now+temp<=n)
		{
			now+=temp;
			cout<<now<<" ";
			continue;
		}
		now-=temp;
		cout<<now<<" ";
	}
	//system("pause");
	return 0;
}

最后总结一下打这次比赛的历程吧
人生第一场CodeForces比赛o.o,虽然只A掉了四道题,但还是挺开心的

A题送分题所以直接就A掉了。。。
其实B一开始用字符直接比对没调出来我就有点慌了,然后去喝了杯水,突然想起来了这样冒泡排序。。。果然水是生命之源啊。。。交了4遍才A。。。真的慌。。。
C一开始也没有列举出来全部情况,交了两遍才A掉。。。
D题最后3分钟一直调试。。。差点就想放弃了。。。慌的不行。。。没想到居然能调出来,放平时估计放弃了。。。
打比赛真的和平时做题不太一样。。。打比赛有一种紧张刺激的畅快感。。。
当然NOIp当然不能在最后3分钟再去调试了。。。最后十分钟大概检查一下就完了吧。。。
不知道NOIp会多大难度。。。还是有点慌。。。
还是多打点比赛积累一下经验吧。。。
其实这场比赛好像我什么算法也没有用。。。

然后,以后写题之前还是要先多想一下再去打代码,比如在纸上列举列举什么的,说不定会事半功倍之类的。。。像B题写出来之后又去重构主体部分就很费时间。。。文化课也是这样吧。。。

最后,答疑好评!
这里写图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值