暑假练习记录(三):2016 CCPC Final

本文精选了多个算法竞赛题目,包括排序、优先队列、贪心算法等,详细解析了如TheThirdCupisFree、Wash、ProblemBuyer等题目的解题思路与代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一,The Third Cup is Free

水题,排序,,,,

#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn=1e5+5;
int a[maxn];
int main(){
	int t,cas=1;scanf("%d",&t);
	while(t--){
		int n,all=0;scanf("%d",&n);
		for(int i=0;i<n;i++){
			scanf("%d",&a[i]);all+=a[i];
		}
		int ans=0;
		sort(a,a+n);
		for(int i=n-1;i>=0;i-=3){
			ans+=a[i-2];
		}
		printf("Case #%d: %d\n",cas++,all-ans);
	}
	return 0;
}

二,Wash

优先队列洗衣服,先洗,以衣服为线从左到右做时间轴,每次存储当前所有洗衣机下一次再用的时间,优先找当前时间下时间距离最近的空闲洗衣机,然后最后一件衣服先烘干然后最大加最小,取个最小值

#include <cstdio>
#include <queue>
#include <algorithm>
#include <cstring>
using namespace std;
typedef long long ll;
const int maxn=1e6+5;
struct node{
	ll x,y;
	friend bool operator<(node a1,node b1)
    {
        return a1.x>b1.x;//小值优先级高
    }
}pa;
priority_queue<node>q1,q2;
ll a[maxn];
int main(){
	int t,cas=1;
	scanf("%d",&t);
	while(t--){
		memset(a,0,sizeof a);
		while(!q1.empty())q1.pop();
		while(!q2.empty())q2.pop();
		int l,n,m;
		scanf("%d%d%d",&l,&n,&m);
		for(int i=0;i<n;i++){
			scanf("%lld",&pa.x);
			pa.y=pa.x;
			q1.push(pa);
		}
		for(int i=0;i<m;i++){
			scanf("%lld",&pa.x);
			pa.y=pa.x;
			q2.push(pa);
		}
		//washing clothes
		for(int i=0;i<l;i++){
			pa=q1.top();
			q1.pop();
			a[i]=pa.x;
			pa.x+=pa.y;
			q1.push(pa);
		}
		ll ans=0;
		//drying clothes
		for(int i=l-1;i>=0;i--){
			pa=q2.top();
			q2.pop();
			//dry the last washing clothes
			ans=max(ans,pa.x+a[i]);
			pa.x+=pa.y;
			q2.push(pa);
		}
		printf("Case #%d: %lld\n",cas++,ans);
	}
	return 0;
}

三,Mr.Panda and Survey

等待补题,,,,,,,

四,Problem Buyer

贪心,优先队列,总之很难想就是了,从易到难存储需要问题难度,区间排序,对每个点,找合适的区间存入优先队列中,不断维护优先队列,最后结果即是n - (int) q.size() +1;

#include <queue>
#include <cstdio>
#include <algorithm>
#include <iostream>
using namespace std;
typedef long long ll;
const int maxn=1e5+5;
struct node{
	int a,b;
	bool operator<(const node &x)const
	{
		if(a!=x.a)return a<x.a;
		else return b>x.b;
	}
}p[maxn];
priority_queue<int,vector<int>,greater<int> > q;
int c[maxn];
int main(){
	int t;scanf("%d",&t);
	for(int cnt=1;cnt<=t;cnt++){
		int n,m;
		scanf("%d%d",&n,&m);
		for(int i=0;i<n;i++){
			scanf("%d%d",&p[i].a,&p[i].b);
		}
		for(int i=0;i<m;i++){
			scanf("%lld",&c[i]);
		}
		sort(c,c+m);sort(p,p+n);
		int ans=-1,pos=0;
		while(!q.empty())q.pop();
		for(int i=0;i<m;i++){
			while(pos<n&&p[pos].a<=c[i]){
				if(p[pos].b>=c[i]){
					q.push(p[pos].b);
				}
				pos++;
			}
			while(!q.empty()&&q.top()<c[i])q.pop();
			if(q.empty()){
				ans=-1;break;
			}
			ans=max(ans,n-(int)q.size()+1);
			q.pop();
		}
		if(ans==-1)printf("Case #%d: IMPOSSIBLE!\n",cnt);
		else printf("Case #%d: %d\n",cnt,ans);
	}
	return 0;
}

五,Periodical Cicadas

等待补题,,,,,,,

六,Pandaland

(等待补题,,,,,,,)

暴力最短路,即枚举各条边删掉,然后每次用Dijkstra寻找该边端点的最小路,加上该边权值,即为以e.from和e.to为端点形成的最小圈权值,取最小值即可,,,,(果然,我就是个菜鸡,小声.jpg)

 

#include <iostream>
#include <cstdio>
#include <map>
#include <set>
#include <vector>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <queue>
#include <deque>
#define inf 2147483647
using namespace std;
typedef long long ll;
typedef pair<int,int> P;

struct edge{
	int from,to,cost;
};
vector<int> G[4005];
vector<edge> ed;
ll d[4005],res;
void dijkstra(int s,int dis){
	priority_queue<P,vector<P>,greater<P> >que;
	fill(d,d+4005,inf);
	d[s]=0;
	que.push(P(0,s));
	while(!que.empty()){
		P p=que.top();
		que.pop();
		int v=p.second;
		if(d[v]+dis>=res)break;
		if(d[v]<p.first)continue;
		for(int i=0;i<G[v].size();i++){
			int u=G[v][i];
			edge e=ed[u];
			if(d[e.to]>d[v]+e.cost){
				d[e.to]=d[v]+e.cost;
				que.push(P(d[e.to],e.to));
			}
		}
	}
}
map<P,int> m;
int main(){
	int t;scanf("%d",&t);
	for(int cas=1;cas<=t;cas++){
		for(int i=0;i<4005;i++){
			G[i].clear();
		}
		ed.clear();
		m.clear();
		int num,cnt=0;
		scanf("%d",&num);
		for(int i=0;i<num;i++){
			int a,b,x,y,cost;
			scanf("%d%d%d%d%d",&a,&b,&x,&y,&cost);
			if(m[P(a,b)]==0)m[P(a,b)]=++cnt;
			if(m[P(x,y)]==0)m[P(x,y)]=++cnt;
			edge e;
			e.cost=cost;
			e.from=m[P(a,b)];
			e.to=m[P(x,y)];
			ed.push_back(e);
			int q=ed.size();
			G[m[P(a,b)]].push_back(q-1);
			e.cost=cost;
			e.to=m[P(a,b)];
			e.from=m[P(x,y)];
			ed.push_back(e);
			G[m[P(x,y)]].push_back(q);
		}
		res=inf;
		for(int i=0;i<ed.size();i+=2){
			edge &e=ed[i];
			int dist=e.cost;
			e.cost=inf;
			ed[i+1].cost=inf;
			dijkstra(e.from,dist);
			res=min(res,d[e.to]+dist);
			e.cost=dist;
			ed[i+1].cost=dist; 
		}
		if(res>=inf)res=0;
		printf("Case #%d: %lld\n",cas,res);
	}
	return 0;
}

 

七,Engineer Assignment

等待补题,,,,,,,

八,Mr. Panda and Crystal

等待补题,,,,,,,

九,Worried School

大模拟,找到忧虑的学校在5个sites的位置pos_x,和国外排名pos_y,wa了n发,结果是pos_x与g忘记判大小了;

#include <map>
#include <iostream>
#include <cstring>
#include <vector> 
#include <algorithm>
using namespace std;
vector<string> a;
string s[6][30],st[30];
int main(){
	int t,cas=1;
	cin>>t;
	while(t--){
		int g;
		string str;
		cin>>g;cin>>str;
		for(int i=0;i<5;i++){
			for(int j=0;j<20;j++){
				cin>>s[i][j];
			}
		}
		for(int i=0;i<20;i++){
			cin>>st[i];
		}
		a.clear();
		bool fla=0;
		for(int i=0;i<20;i++){
			for(int j=0;j<5;j++){
				if(str==s[j][i]){
					fla=1;break;
				}
				a.push_back(s[j][i]);
				
			}
			if(fla)break;
		}
		sort(a.begin(),a.end());
		a.erase(unique( a.begin(), a.end() ), a.end());
		int posx=a.size();
		for(int i=0;i<20;i++){
			if(str==st[i])break;
			a.push_back(st[i]);
		}
		sort(a.begin(),a.end());
		a.erase(unique( a.begin(), a.end() ), a.end());
		int mx=a.size();
		printf("Case #%d: ",cas++);
		if(a.size()>=g){
			if(posx>=g)printf("0\n");
			else printf("%d\n",g-posx);
		}else printf("ADVANCED!\n");
	}	
	return 0;
}

十,Lazors

等待补题,,,,,,,

十一,Daylight Saving Time

打表,日历,记得pst,pdt,neither,both区别,和3月时候是第二个星期日

#include <cstdio>
using namespace std;
struct node{
	int y,m,d,h,mi,s;
	bool operator<(const node &b)const
	{
		if(y!=b.y)return y<b.y;
		else if(m!=b.m)return m<b.m;
		else if(d!=b.d)return d<b.d;
		else if(h!=b.h)return h<b.h;
		else if(mi!=b.mi)return mi<b.mi;
		else return s<b.s;
	}
}; 
int sstod[105],dtos[105];
int main(){
	int n,t,cas=0;
	scanf("%d",&t);
	sstod[7]=11,dtos[7]=4;
	for(int i=8;i<=100;i++){
		if(i%4||i%100==0){
			sstod[i]=sstod[i-1]-1;
			if(sstod[i]<=7)sstod[i]+=7;
			dtos[i]=dtos[i-1]-1;
			if(dtos[i]<1)dtos[i]+=7;
		}else{
			sstod[i]=sstod[i-1]-2;
			if(sstod[i]<=7)sstod[i]+=7;
			dtos[i]=dtos[i-1]-2;
			if(dtos[i]<1)dtos[i]+=7;
		}
	}
	while(t--){
		node now;
		scanf("%d-%d-%d %d:%d:%d",&now.y,&now.m,&now.d,&now.h,&now.mi,&now.s);
		node st={now.y,3,sstod[now.y-2000],2,0,0};
		node ne={now.y,3,sstod[now.y-2000],3,0,0};
		node dt={now.y,11,dtos[now.y-2000],1,0,0};
		node bt={now.y,11,dtos[now.y-2000],2,0,0};
		if(now<st)printf("Case #%d: PST\n",++cas);
		else if(now<ne)printf("Case #%d: Neither\n",++cas);
		else if(now<dt)printf("Case #%d: PDT\n",++cas);
		else if(now<bt)printf("Case #%d: Both\n",++cas);
		else printf("Case #%d: PST\n",++cas);
	}
	return 0;
}

 打的死惨死惨的,呜呜呜,睡觉睡觉,,,

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值