zoukankan      html  css  js  c++  java
  • 2017 United Kingdom and Ireland Programming Contest (UKIEPC 2017)

    A. Alien Sunset

    暴力枚举答案即可。

    #include<cstdio>
    int n,i,mx;
    struct P{
    	int h,r,t;
    	bool night(int x){
    		x%=h;
    		if(r<=t)return x<=r||x>=t;
    		return x<=r&&x>=t;
    	}	
    }a[50];
    inline bool check(int x){
    	for(int i=0;i<n;i++)if(!a[i].night(x))return 0;
    	return 1;
    }
    int main(){
    	scanf("%d",&n);
    	for(i=0;i<n;i++){
    		scanf("%d%d%d",&a[i].h,&a[i].r,&a[i].t);
    		if(a[i].h>mx)mx=a[i].h;
    	}
    	for(i=0;i<1825*mx;i++)if(check(i))return printf("%d",i),0;
    	puts("impossible");
    }
    

      

    B. Breaking Biscuits

    等价于选择一对距离最小的平行线夹住所有点。

    枚举一条边,计算两侧所有点到这条直线的距离的最大值即可。

    时间复杂度$O(n^3)$。

    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    const int N=111;
    struct P{
    	int x,y;
    	P(){}
    	P(int _x,int _y){x=_x,y=_y;}
    	P operator-(P b){return P(x-b.x,y-b.y);}
    	double len(){return hypot(x,y);}
    }a[N];
    int n,i,j,k;
    double cross(P a,P b){return a.x*b.y-a.y*b.x;}
    double dist(P p,P a,P b){
    	return cross(p-a,b-a)/(b-a).len();
    }
    int main(){
    	scanf("%d",&n);
    	for(i=1;i<=n;i++)scanf("%d%d",&a[i].x,&a[i].y);
    	double ans=1e100;
    	a[n+1]=a[1];
    	for(i=1;i<=n;i++)for(j=1;j<i;j++){
    		double l=1e100,r=-1e100;
    		for(k=1;k<=n;k++){
    			l=min(l,dist(a[k],a[i],a[j]));
    			r=max(r,dist(a[k],a[i],a[j]));
    		}
    		r-=l;
    		ans=min(ans,r);
    	}
    	printf("%.10f",ans);
    }
    

      

    C. Cued In

    按题意模拟即可。

    #include<stdio.h>
    #include<iostream>
    #include<string.h>
    #include<string>
    #include<ctype.h>
    #include<math.h>
    #include<set>
    #include<map>
    #include<vector>
    #include<queue>
    #include<bitset>
    #include<algorithm>
    #include<time.h>
    using namespace std;
    const int N = 3e5 + 10;
    const int inf = 1e9;
    int casenum, casei;
    int c[2010], e[15];
    int n;
    map<string, int> mop;
    int num[10];
    char s[20];
    int main()
    {
    	mop["red"] = 1; mop["yellow"] = 2; mop["green"] = 3; mop["brown"] = 4;
    	mop["blue"] = 5; mop["pink"] = 6; mop["black"] = 7;
    	while(~scanf("%d", &n)){
    		for(int i = 1; i <= n; i ++){
    			scanf("%s", s);
    			num[mop[s]] ++;
    		}
    		int top = 1;
    		for(int i = 2; i <= 7; i ++){
    			if(num[i]) top = i;
    		}
    		if(top == 1) puts("1");
    		else{
    			int ans = 0;
    			ans = (1 + top) * num[1];
    			for(int i = 2; i <= 7; i ++) ans += num[i] * i;
    			printf("%d
    ", ans);
    		}
    		
    		
    	}
    	return 0;
    }
    /*
    
    
    */
    

      

    D. Deranging Hat

    求出最终位置,然后贪心置换即可。

    #include<stdio.h>
    #include<iostream>
    #include<string.h>
    #include<string>
    #include<ctype.h>
    #include<math.h>
    #include<set>
    #include<map>
    #include<vector>
    #include<queue>
    #include<bitset>
    #include<algorithm>
    #include<time.h>
    using namespace std;
    const int N = 1e5 + 10;
    char s[N];
    struct A
    {
    	char ch;
    	int now;
    	bool operator < (const A & b)const
    	{
    		if(ch != b.ch)return ch < b.ch;
    		return now < b.now;
    	}
    }a[N];
    int pos_to_o[N];
    int main()
    {
    	while(~scanf("%s", s))
    	{
    		int n = strlen(s);
    		for(int i = 0; i < n; ++i)
    		{
    			a[i].ch = s[i];
    			a[i].now = i;
    		}
    		sort(a, a + n);
    		for(int i = 0; i < n; ++i)
    		{
    			pos_to_o[a[i].now] = i;
    		}
    		vector<pair<int, int> >ans;
    		for(int i = 0; i < n; ++i)
    		{
    			//我们要考虑移动,把位置为a[i].now的数,移动到位置i,那位置i的数的位置变成了a[i].now
    			if(a[i].now != i)
    			{
    				ans.push_back(make_pair(i, a[i].now));
    				int p = a[i].now;
    				int o = pos_to_o[i];
    				a[o].now = a[i].now;
    				pos_to_o[p] = o;
    			}
    		}
    		int g = ans.size() - 1;
    		for(int i = g; i >= 0; --i)
    		{
    			printf("%d %d
    ", ans[i].second + 1, ans[i].first + 1);
    		}
    	}
    	return 0;
    }
    /*
    
    
    */
    

      

    E. Education

    按人数从大到小考虑,每次选择满足条件的最便宜的房子。

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const int N=5010;
    int n,m,i,a[N],b[N],c[N],q[N],ans[N];
    bool cmp(int x,int y){return a[x]<a[y];}
    int ask(int x){
    	int t=0,f=~0U>>1;
    	for(int i=1;i<=m;i++)if(b[i]>=x){
    		if(c[i]<f)f=c[i],t=i;
    	}
    	return t;
    }
    int main(){
    	scanf("%d%d",&n,&m);
    	for(i=1;i<=n;i++)scanf("%d",&a[i]),q[i]=i;
    	for(i=1;i<=m;i++)scanf("%d",&b[i]);
    	for(i=1;i<=m;i++)scanf("%d",&c[i]);
    	sort(q+1,q+n+1,cmp);
    	for(i=n;i;i--){
    		int x=ask(a[q[i]]);
    		if(!x)return puts("impossible"),0;
    		b[x]=0;
    		ans[q[i]]=x;
    	}
    	for(i=1;i<=n;i++)printf("%d ",ans[i]);
    }
    

      

    F. Flipping Coins

    $f[i][j]$表示还需要操作$i$次,目前有$j$枚硬币朝上时的最大期望正面向上的硬币数。

    时间复杂度$O(nk)$。

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const int N=444;
    double f[N][N],ans;
    int n,m,i,j;
    int main(){
    	scanf("%d%d",&n,&m);
    	for(i=1;i<=n;i++)f[0][i]=i;
    	for(i=1;i<=m;i++)for(j=0;j<=n;j++){
    		if(j)f[i][j]=(f[i-1][j]+f[i-1][j-1])/2;
    		if(j<n)f[i][j]=max(f[i][j],(f[i-1][j]+f[i-1][j+1])/2);
    	}
    	printf("%.10f",f[m][0]);
    }
    

      

    G. GentleBots

    设估价函数为两点到终点的曼哈顿距离之和,每次选取使得估价函数最优的方向走,若不能走,则随机抖动。

    #include<cstdio>
    #include<ctime>
    #include<cstdlib>
    #include<algorithm>
    using namespace std;
    const int dx[7]={1,-1,0,0,0,0,0},
    		  dy[7]={0,0,-1,1,0,0,0},
    		  dz[7]={0,0,0,0,1,-1,0};
    struct P{
    	int x,y,z;
    	void read(){
    		scanf("%d%d%d",&x,&y,&z);
    	}
    	int dis(P b){
    		return abs(x-b.x)+abs(y-b.y)+abs(z-b.z);
    	}
    	void write(){
    		printf("(%d %d %d)",x,y,z);
    	}
    	P(){}
    	P(int _x,int _y,int _z){x=_x,y=_y,z=_z;}
    	P apply(int d){
    		return P(x+dx[d],y+dy[d],z+dz[d]);
    	}
    }A,B,C,D;//A->B C->D
    int main(){
    	A.read();
    	B.read();
    	C.read();
    	D.read();
    	while(1){
    		A.write();
    		putchar(' ');
    		C.write();
    		puts("");
    		int pre=A.dis(B)+C.dis(D);
    		if(!pre)return 0;
    		int best=~0U>>1;
    		int I=0,J=0;
    		for(int i=0;i<7;i++)for(int j=0;j<7;j++){
    			P NA=A.apply(i),NC=C.apply(j);
    			if(!NA.dis(C))continue;
    			if(!NA.dis(NC))continue;
    			if(!NC.dis(A))continue;
    			if(!NC.dis(NA))continue;
    			int now=NA.dis(B)+NC.dis(D);
    			if(now<best)best=now,I=i,J=j;
    		}
    		if(best>=pre){
    			while(1){
    				int i=rand()%7,j=rand()%7;
    				P NA=A.apply(i),NC=C.apply(j);
    				if(!NA.dis(C))continue;
    				if(!NA.dis(NC))continue;
    				if(!NC.dis(A))continue;
    				if(!NC.dis(NA))continue;
    				I=i,J=j;
    				break;
    			}
    		}
    		A=A.apply(I);
    		C=C.apply(J);
    	}
    }
    

      

    H. Hiker Safety

    能走就走,用队列维护所有可能走的人,时间复杂度$O(n^2)$。

    #include<cstdio>
    const int N=10010;
    int B,m,i,n,d[N],a[N],pos[N],r;
    int h,t,x,q[10000000];
    int cnt,fin[3333333];
    inline int abs(int x){return x>0?x:-x;}
    inline bool check(int x){
    	if(pos[x]==m)return 0;
    	int pre=x-1,nxt=x+1;
    	if(nxt>r)nxt=0;
    	if(pre){
    		if(abs(d[pos[x]+1]-d[pos[pre]])>B)return 0;
    		if(abs(d[pos[x]+1]-d[pos[pre]])<a[x])return 0;
    		if(abs(d[pos[x]+1]-d[pos[pre]])<a[pre])return 0;
    	}
    	if(nxt){
    		if(abs(d[pos[x]+1]-d[pos[nxt]])>B)return 0;
    		if(abs(d[pos[x]+1]-d[pos[nxt]])<a[x])return 0;
    		if(abs(d[pos[x]+1]-d[pos[nxt]])<a[nxt])return 0;
    	}
    	return 1;
    }
    inline void gao(int x){
    	//printf("->%d
    ",x);
    	pos[x]++;
    	fin[++cnt]=x;
    	while(r&&pos[r]==m)r--;
    	if(x>1)q[++t]=x-1;
    	if(x<r)q[++t]=x+1;
    	if(x<=r)q[++t]=x;
    }
    int main(){
    	scanf("%d%d",&B,&m);
    	for(i=1;i<=m;i++)scanf("%d",&d[i]);
    	for(i=1;i<m;i++)if(d[i]>d[i+1])while(1);
    	scanf("%d",&n);
    	for(i=1;i<=n;i++){
    		scanf("%d%d",&a[i],&pos[i]);
    	}
    	for(i=1;i<=n;i++){
    		if(pos[i]<m)r=i;
    	}
    	//[1,r]
    	h=1,t=0;
    	for(i=1;i<=r;i++)q[++t]=i;
    	while(h<=t){
    		x=q[h++];
    		if(check(x)){
    			gao(x);
    		}
    	}
    	for(i=1;i<=n;i++)if(pos[i]<m)return puts("impossible"),0;
    	for(i=1;i<=cnt;i++)printf("%d ",fin[i]);
    }
    

      

    I. I Work All Day

    按题意模拟即可。

    #include<stdio.h>
    #include<iostream>
    #include<string.h>
    #include<string>
    #include<ctype.h>
    #include<math.h>
    #include<set>
    #include<map>
    #include<vector>
    #include<queue>
    #include<bitset>
    #include<algorithm>
    #include<time.h>
    using namespace std;
    const int N = 3e5 + 10;
    const int inf = 1e9;
    int casenum, casei;
    int c[15], e[15];
    int n;
    int main()
    {
    	while(~scanf("%d", &n))
    	{
    		for(int i = 0; i < n; ++i)scanf("%d", &c[i]);
    		int T; scanf("%d", &T);
    		int ans = c[0]; int val = T % c[0];
    		for(int i = 1; i < n; ++i)
    		{
    			if(T % c[i] < val)
    			{
    				val = T % c[i];
    				ans = c[i];
    			}
    		}
    		printf("%d
    ", ans);
    	}
    	return 0;
    }
    /*
    
    
    */
    

      

    J. Just A Minim

    按题意模拟即可。

    #include<stdio.h>
    #include<iostream>
    #include<string.h>
    #include<string>
    #include<ctype.h>
    #include<math.h>
    #include<set>
    #include<map>
    #include<vector>
    #include<queue>
    #include<bitset>
    #include<algorithm>
    #include<time.h>
    using namespace std;
    const int N = 3e5 + 10;
    const int inf = 1e9;
    int casenum, casei;
    int c[2010], e[15];
    int n;
    int main()
    {
    	while(~scanf("%d", &n))
    	{
    		for(int i = 0; i < n; ++i)scanf("%d", &c[i]);
    		double ans = 0;
    		for(int i = 0; i < n; i ++){
    			if(c[i] == 0) ans += 2;
    			else if(c[i] == 1) ans += 1;
    			else if(c[i] == 2) ans += 0.5;
    			else if(c[i] == 4) ans += 0.25;
    			else if(c[i] == 8) ans += 0.125;
    			else if(c[i] == 16) ans += 0.0625;
    		}
    		printf("%.8f
    ", ans);
    	}
    	return 0;
    }
    /*
    
    
    */
    

      

    K. Knightsbridge Rises

    拆点求最大流。

    #include<stdio.h>
    #include<iostream>
    #include<string.h>
    #include<string>
    #include<ctype.h>
    #include<math.h>
    #include<set>
    #include<map>
    #include<vector>
    #include<queue>
    #include<bitset>
    #include<algorithm>
    #include<time.h>
    using namespace std;
    const int N = 305, M = N * N * 8;
    const int inf = 0x3f3f3f3f;
    #define MS(x, y) memset(x, y, sizeof(x))
    int n;
    int L[N], W[N];
    int ST, ED;
    int first[N], ID;
    int w[M], cap[M], nxt[M];
    void ins(int x, int y, int cap_)
    {
    	w[++ID] = y;
    	cap[ID] = cap_;
    	nxt[ID] = first[x];
    	first[x] = ID;
    	
    	w[++ID] = x;
    	cap[ID] = 0;
    	nxt[ID] = first[y];
    	first[y] = ID;
    }
    int d[N];
    bool bfs()
    {
    	MS(d, -1);
    	queue<int>q; q.push(ST); d[ST] = 0;
    	while(!q.empty())
    	{
    		int x = q.front(); q.pop();
    		for(int z = first[x]; z; z = nxt[z])if(cap[z])
    		{
    			int y = w[z];
    			if(d[y] == -1)
    			{
    				d[y] = d[x] + 1;
    				q.push(y);
    				if(y == ED)return 1;
    			}
    		}
    	}
    	return 0;
    }
    int dfs(int x, int all)
    {
    	if(x == ED)return all;
    	int use = 0;
    	for(int z = first[x]; z; z = nxt[z])if(cap[z])
    	{
    		int y = w[z];
    		if(d[y] == d[x] + 1)
    		{
    			int tmp = dfs(y, min(cap[z], all - use));
    			cap[z] -= tmp;
    			cap[z ^ 1] += tmp;
    			use += tmp;
    			if(use == all)break;
    		}
    	}
    	if(use == 0)d[x] = -1;
    	return use;
    }
    int dinic()
    {
    	int ret = 0;
    	while(bfs())ret += dfs(ST, inf);
    	return ret;
    }
    vector<int>vt[N];
    void go(int o, int x)
    {	
    	for(int z = first[x]; z; z = nxt[z])if((z & 1) && cap[z])
    	{
    		x = w[z];
    		break;
    	}
    	if(x == 0)
    	{
    		//for(auto it : vt[o])
    		/*
    		int cnt = 0;
    		for(int ii = 0; ii < vt[o].size(); ++ii)
    		{
    			int it = vt[o][ii];
    			if(++cnt == 1)printf("%d", it);
    			else printf(" %d", it);
    		}
    		puts("");
    		*/
    		return;
    	}
    	vt[o].push_back(x - n);
    	go(o, x - n);
    }
    int main()
    {
    	while(~scanf("%d", &n))
    	{
    		MS(first, 0); ID = 1;
    		ST = 0;
    		for(int i = 1; i <= n; ++i)
    		{
    			scanf("%d%d", &W[i], &L[i]);
    			if(W[i] == 0)
    			{
    				ins(ST, i, 1);
    			}
    			ins(i, n + i, 1);
    		}
    		for(int i = 1; i <= n; ++i)
    		{
    			for(int j = 1; j <= n; ++j)if(j != i && L[i] >= W[j])
    			{
    				ins(n + i, j, 1);
    			}
    		}
    		int m;
    		scanf("%d", &m);
    		ED = n + n + m + 1;
    		for(int i = 1; i <= m; ++i)
    		{
    			int x;
    			scanf("%d", &x);
    			ins(n + n + i, ED, 1);
    			for(int j = 1; j <= n; ++j)if(L[j] >= x)
    			{
    				ins(n + j, n + n + i, 1);
    			}
    		}
    		if(dinic() != m)
    		{
    			puts("impossible");
    		}
    		else
    		{
    			for(int z = first[ED]; z; z = nxt[z])if((z & 1) && cap[z])
    			{
    				vt[w[z] - n - n].clear();
    				go(w[z] - n - n, w[z]);
    			}
    			for(int o = 1; o <= m; ++o)
    			{
    				int cnt = 0;
    				for(int ii = vt[o].size() - 1; ii >= 0; --ii)
    				{
    					int it = vt[o][ii];
    					if(++cnt == 1)printf("%d", it);
    					else printf(" %d", it);
    				}
    				puts("");
    			}
    		}
    	}
    	return 0;
    }
    /*
    5
    0 1
    1 2
    2 3
    3 4
    0 2
    2
    4 2
    
    7
    0 1
    1 4
    0 3
    0 1
    2 5
    2 5
    1 2
    3
    5 4 5
    
    2
    0 1
    5 3
    2
    2 1
    
    */
    

      

    L. Lounge Lizards

    将所有点到原点的方向向量约分后分组,每组按距离从小到大排序,然后求LIS。

    时间复杂度$O(nlog n)$。

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    const int N=1000010;
    int n,i,j,k,m,f[N],ans;
    struct P{int x,y,h;ll w;}a[N],O;
    ll sqr(ll x){return x*x;}
    int gcd(int a,int b){return b?gcd(b,a%b):a;}
    inline bool cmp(const P&a,const P&b){
    	if(a.x!=b.x)return a.x<b.x;
    	if(a.y!=b.y)return a.y<b.y;
    	return a.w<b.w;
    }
    inline void ins(int x){
    	if(!m||x>f[m]){
    		f[++m]=x;
    		return;
    	}
    	int l=1,r=m,mid,t;
    	while(l<=r){
    		mid=(l+r)>>1;
    		if(f[mid]>=x)r=(t=mid)-1;else l=mid+1;
    	}
    	f[t]=x;
    }
    int main(){
    	scanf("%d%d",&O.x,&O.y);
    	scanf("%d",&n);
    	for(i=1;i<=n;i++){
    		scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].h);
    		a[i].x-=O.x;
    		a[i].y-=O.y;
    		a[i].w=sqr(a[i].x)+sqr(a[i].y);
    		//sgn gcd
    		int d=gcd(abs(a[i].x),abs(a[i].y));
    		a[i].x/=d,a[i].y/=d;
    		//printf("%d %d %lld
    ",a[i].x,a[i].y,a[i].w);
    	}
    	sort(a+1,a+n+1,cmp);
    	for(i=1;i<=n;i=j){
    		for(j=i;j<=n&&a[i].x==a[j].x&&a[i].y==a[j].y;j++);
    		m=0;
    		for(k=i;k<j;k++){
    			ins(a[k].h);
    		}
    		ans+=m;
    	}
    	printf("%d",ans);
    }
    /*
    0 0
    6
    0 -1 2
    0 -2 2
    0 -3 3
    0 1 1
    0 2 2
    0 3 1
    */
    

      

  • 相关阅读:
    Swap file ".hive-site.xml.swp" already exists
    Hbase启动hbase shell运行命令报Class path contains multiple SLF4J bindings.错误
    hbase启动后HMaster进程自动关闭
    Hadoop数据分析平台项目实战(基于CDH版本集群部署与安装)
    Exception in thread "main" java.lang.UnsatisfiedLinkError: org.apache.hadoop.io.nativeio.NativeIO$Windows.access0(Ljava/lang/String;I)Z
    Exception in thread "main" java.lang.NullPointerException
    eclipse工具下hadoop环境搭建
    18/03/18 04:53:44 WARN TaskSchedulerImpl: Initial job has not accepted any resources; check your cluster UI to ensure that workers are registered and have sufficient resources
    java.net.ConnectException: Call From slaver1/192.168.19.128 to slaver1:8020 failed on connection exception: java.net.ConnectException: Connection refused; For more details see: http://wiki.apache.org
    从gitlab下载下来的maven无法运行,老报404解决方法
  • 原文地址:https://www.cnblogs.com/clrs97/p/7768748.html
Copyright © 2011-2022 走看看