Codeforces #398 div2 A-D

传送门:Codeforce #398

这次比赛说来好气啊,就搞出一个A来,其实B和C都不是很难的,但是比赛的时候大家出题都很慢,我也就自然而然的认为很难了。。还是菜啊。

A题没什么好说的,就是题意有点难懂,结合note能明白个差不多,直接贴上代码:

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<string>
#include<math.h>
#include<algorithm>
#include<queue>
#include<stack>
#include<set>
#include<vector>
#include<map>
#define ll long long
#define pi acos(-1)
#define inf 0x3f3f3f3f
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
using namespace std;
typedef pair<int,int>P;
const int MAXN=100010;
int a[MAXN],book[MAXN];
int main()
{
	int n;
	cin>>n;
	for(int i=1;i<=n;i++)
	cin>>a[i];
	int t=n;
	for(int i=1;i<=n;i++)
	{
		if(a[i]==t)
		{
			printf("%d ",a[i]);
			while(t--)
			{
				if(book[t])
				{
					printf("%d ",t);
				}
				else
				break;
			}
			puts("");
		}
		else
		{
			book[a[i]]=1;
			puts("");
		}
	}
    return 0;
}

B题:

题意:看病排队,给出每个人到的时间点和看病所需要的时间,问男主什么时候去等待时间最少,如果男主和别人同时到那么男主最后看病。

思路:因为他只要求等待时间最少,并没有要求去的尽可能早(然而我一开始就是这么理解的),不难发现最短的等待时间肯定是卡在某个人前一分钟去。然后模拟就好了。

代码:

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<string>
#include<math.h>
#include<algorithm>
#include<queue>
#include<stack>
#include<set>
#include<vector>
#include<map>
#define ll long long
#define pi acos(-1)
#define inf 0x3f3f3f3f3f3f3f3f
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
using namespace std;
typedef pair<int,int>P;
const int MAXN=100010;
ll a[MAXN];
int main()
{
	ll s,e,k;
	ll n;
	cin>>s>>e>>k;
	cin>>n;
	for(int i=0;i<n;i++)
	{
		cin>>a[i];
	}
	ll t,now=s,ans=0;
	int mint=inf;
	for(int i=0;i<n;i++)
	{
		t=a[i];
		if(now>=t)
		{
			int temp=1;
			while(a[i+1]==t)
			{
				temp++;
				i++;
			}
			if(now+k*temp-t+1<mint)
			{
				mint=now+k*temp-t+1;
				ans=t-1;
			}
			now+=k*temp;
			if(now>=e)
			break;
		}
		else
		{
			printf("%lld",now);
			return 0;
		}
	}
	if(s+k*n<=e-k)
	ans=e-k;
	printf("%lld",ans);
    return 0;
}

C题:

题意:给定一颗树和每个点的点权,问能不能剪断某两条边使之分成三部分并且每部分的点权和相等。

思路:因为要分成三部分,所以先求出每部分应该多大,然后dfs两次,注意标记数组不要清空。

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<string>
#include<math.h>
#include<algorithm>
#include<queue>
#include<stack>
#include<set>
#include<vector>
#include<map>
#define ll long long
#define pi acos(-1)
#define inf 0x3f3f3f3f
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
using namespace std;
typedef pair<int,int>P;
const int MAXN=1000010;
vector<int>v[MAXN];
int w[MAXN],book[MAXN],vis[MAXN];
int sum=0,T,flag,root,kk=0;
int dfs(int u)
{
	book[u]=1;
	int ans=0;
	for(int i=0;i<v[u].size();i++)
	{
		if(!book[v[u][i]]&&!vis[v[u][i]])
		{
			ans+=dfs(v[u][i]);	
			if(flag)
			return ans;
		}
	}
	ans+=w[u];
	if(ans==sum&&u!=root)
	{
		flag=1,T=u;
		vis[u]=1;
		return ans;
	}
	return ans;
}
int main()
{
	int n,a,b;
	cin>>n;
	sum=0;
	for(int i=1;i<=n;i++)
	{
		scanf("%d%d",&a,&b);
		if(!a)
		root=i;
		if(a)
		v[a].push_back(i);
		w[i]=b;
		sum+=b;
	}
	if(sum%3)
	{
		cout<<-1;
		return 0;
	}
	else
	{
		int k1=-1,k2=-1;
		flag=0;
		sum/=3;
		dfs(root);
		if(flag)
		k1=T;
		flag=0;
		memset(book,0,sizeof(book));
		dfs(root);
		if(flag)
		k2=T;
		if(k1==-1||k2==-1||k1==root||k2==root)
		cout<<-1;
		else
		cout<<k1<<' '<<k2;
	}
    return 0;
}
D题:

题意:男主(也可能是女主)喝牛奶,已知每天喝k盒,冰箱里有n盒,超市里有m盒,知道这n+m盒的保质期,问能否在过期之前把冰箱里的都喝完,如果能的话最多再从超市里买多少盒,并输出对应的序号。

思路:贪心+二分,先判断能不能把冰箱里的喝完,然后将超市里的牛奶按保质期排序,然后二分数量,判断如果买保质期长的那一半能不能喝完。

代码:

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<string>
#include<math.h>
#include<algorithm>
#include<queue>
#include<stack>
#include<set>
#include<vector>
#include<map>
#define ll long long
#define pi acos(-1)
#define inf 0x3f3f3f3f
using namespace std;
typedef pair<int,int>P;
const int MAXN=1000010;
vector<P>v;
vector<P>::iterator it;
int a[MAXN],book[MAXN*10];
int n,m,k;
bool check(int j)
{
	int i=0,last=0;
	while(i<n||j<m)
	{
		if((i<n&&a[i]<last)||(j<m&&v[j].first<last))
		return 0;
		for(int x=0;x<k;x++)
		{
			if(i<n&&(j>=m||a[i]<v[j].first))
			i++;
			else
			j++;
		}
		last++;
	}
	return 1;
}
int main()
{
	int b,cnt=0;
	scanf("%d%d%d",&n,&m,&k);
	for(int i=0;i<n;i++)
	scanf("%d",a+i);
	for(int i=1;i<=m;i++)
	{
		scanf("%d",&b),v.push_back(make_pair(b,i));
	}
	sort(a,a+n);
	/*int t=inf;//这里这个判断-1的方法是我自己写的,也能AC,下面那个是看的别人的博客,感觉方法很妙很简练。
	for(int i=n-1;i>=0;i--)
	{
		t=min(t,a[i]);
		book[t]++;
		if(book[t]==k)
		t--;
		if(t<0&&i>0)
		{
			printf("-1");
			return 0;
		}
	}*/
	if(!check(m))
	{
		printf("-1");
		return 0;
	}
	sort(v.begin(),v.end());
	int l=0,r=m,mid;
	while(l<=r)
	{
		mid=(l+r)>>1;
		if(check(mid))
		r=mid-1;
		else
		l=mid+1;
	}
	printf("%d\n",m-l);
	for(int i=l;i<m;i++)
	{
		printf("%d ",v[i].second);
	}
    return 0;
}


这几个题代码写的都很丑,将就看吧。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值