Codeforces Round #611 (Div. 3)

A. Minutes Before the New Year

传送门

题意:
给一个本地时间求它离24小时制(24:00)的分钟差值
思路:
题目给了一个h(小时)和m(分钟数)只需计算 (24-h)*60-m即可

/*
Keep clam  Believe youself
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define Xiaobo main
using namespace std;
const int maxn=2e5+7;
const int mod=1e9+7;
const double eps=1e-15;
const double pi=acos(-1);
const int INF=0x3f3f3f;
typedef long long ll;
ll read(){
     ll c = getchar(),Nig = 1,x = 0;while(!isdigit(c) && c!='-')c = getchar();if(c == '-')Nig = -1,c = getchar();while(isdigit(c))x = ((x<<1) + (x<<3)) + (c^'0'),c = getchar();return Nig*x;}
ll gcd(ll a,ll b){
      return b==0?a:gcd(b,a%b);}
int Xiaobo()
{
     
	int h,m;
	int t;
	scanf("%d",&t);
	while(t--) {
     
		scanf("%d%d",&h,&m);
		int ans=(24-h)*60-m;
		cout<<ans<<'\n';
	}
}

B. Candies Division

传送门:
题意:
圣诞老人说要发n个糖果给k个孩子但是需要满足以下两个条件:
记发完之后这些孩子中最大糖果数为b,最小糖果数为a
(1)b-a<=1;
(2)拥有a+1的糖果数的人不超过(k/2)向下取整。
思路:
很简单的一个思路就是先看n是否能整除k,能就输出,否则就看n%k的余数,最多取k/2 所以只需要n/k+min(n%k,k/2)即可

/*
Keep clam  Believe youself
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define Xiaobo main
using namespace std;
const int maxn=2e5+7;
const int mod=1e9+7;
const double eps=1e-15;
const double pi=acos(-1);
const int INF=0x3f3f3f;
typedef long long ll;
ll read(){
     ll c = getchar(),Nig = 1,x = 0;while(!isdigit(c) && c!='-')c = getchar();if(c == '-')Nig = -1,c = getchar();while(isdigit(c))x = ((x<<1) + (x<<3)) + (c^'0'),c = getchar();return Nig*x;}
ll gcd(ll a,ll b){
      return b==0?a:gcd(b,a%b);}
int Xiaobo()
{
     
	int t;
	scanf("%d",&t);
	while(t--) {
     
		int n,k;
		scanf("%d%d",&n,&k);
		int ans;
		if(n%k==0) ans=n;
		else ans=(n/k)*k,ans+=min(n%k,k/2);
		cout<<ans<<'\n';
	}
}

C. Friends and Gifts

题意:
n个小朋友互相送礼物给剩余的其他小朋友,不能送给自己,题目给出了n个数字,第i个数字就是第i个小朋友要送把礼物送给的那个小朋友的编号,有可能第i个数字为0代表第i个小朋友还没有礼物可送,让求:每个小朋友只接受一个礼物,也只送出一个礼物。
思路:
刚开始想用DFS搜索,对于a[i]=0的小朋友找他谁送给他的,看看那个人有没有人送,如果没人送就送给他,否则然后一直找下去,可是这样有可能导致一个人只有自己一个人可送,所以失败了。
仔细想想,这又是一张图,每个小朋友都有一个入度和出度。满足题目的意思就是建立有向有环图。所以我们可以假定三个集合:
(1)vout:入度不为0,出度为0 :对应的是有人送自己礼物,但是自己没送出
(2)vin:入度为0,出度为0:对应的是没人送自己礼物,但自己送给了别人
(3)v:入度,出度都为0;
在这种情况下,我们便可以对输入的数建图形成3个集合,对于这三个集合的解决方法其实就是让vout和vin里面的点连接起来形成一个环,如果v里面的点大于1那么可以自己形成一个环,否则把这个点接到vout里面,然后再将vout和vin里面的点连接起来即可。
代码

/*
Keep clam  Believe youself
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define Xiaobo main
using namespace std;
const int maxn=2e5+7;
const int mod=1e9+7;
const double eps=1e-15;
const double pi=acos(-1);
const int INF=0x3f3f3f;
typedef long long ll;
ll read(){
     ll c = getchar(),Nig = 1,x = 0;while(!isdigit(c) && c!='-')c = getchar();if(c == '-')Nig = -1,c = getchar();while(isdigit(c))x = ((x<<1) + (x<<3)) + (c^'0'),c = getchar();return Nig*x;}
ll gcd(ll a,ll b){
      return b==0?a:gcd(b,a%b);}
vector<int>vout;
vector<int>vin;
vector<int>v;
struct st {
     
	int in;
	int out;
}g[maxn];
int Xiaobo()
{
     
	int n;
	scanf("%d",&n);
	memset(g,0,sizeof(g));
	for(int i=1;i<=n;i++) {
     
		int k;
		scanf("%d",&k);
		if(!k) continue;
		g[k].in=i;
		g[i].out=k;
	}
	for(int i=1;i<=n;i++) {
     
		if(g[i].in!=0&&g[i].out==0) vout.push_back(i);
		if(g[i].in==0&&g[i].out!=0) vin.push_back(i);
		if(g[i].in==0&&g[i].out==0) v.push_back(i);
	}
	if(v.size()>1)  {
     
		int start =v[0] , end=v[(v.size()-1)];
		int first=v[0];
		for(int i=1;i<v.size()-1;i++) {
     
			g[start].out=v[i];
			start=v[i];
		} 
		g[start].out=end;
		g[end].out=first;
	} 
	else if(v.size()==1){
     
		int cur=vout[vout.size()-1];
		g[cur].out=v[0];
		g[v[0]].in=cur;
		vout.pop_back();
		vout.push_back(v[0]);
	}
	int cur,next;
	for(int i=0;i<vin.size();i++) {
     
		cur=vout[i];
		next=vin[i];
		g[cur].out=next;
	}
	for(int i=1;i<=n;i++) {
     
		printf("%d ",g[i].out);
	}
}

你可能感兴趣的:(Acm之旅_____建图)