ACM-ICPC国际大学生程序设计竞赛北京赛区(2017)网络赛(A+E+F+G+I)

目录

A - Visiting Peking University(模拟)

E - Territorial Dispute(数学几何+思维)

F - Cake(思维)

G - Bounce(找规律)

I - Minimum(线段树模板题)


A - Visiting Peking University(模拟)

Ming is going to travel for n days and the date of these days can be represented by n integers: 0, 1, 2, …, n-1. He plans to spend m consecutive days(2 ≤ m ≤ n)in Beijing. During these m days, he intends to use the first day and another day to visit Peking university. Before he made his plan, Ming investigated on the number of tourists who would be waiting in line to enter Peking university during his n-day trip, and the results could be represented by an integer sequence p[i] (0 ≤ i ≤ n-1, p[i] represents the number of waiting tourists on day i). To save time, he hopes to choose two certain dates a and b to visit PKU(0 ≤ a < b ≤ n-1), which makes p[a] + p[b] as small as possible.

Unfortunately, Ming comes to know that traffic control will be taking place in Beijing on some days during his n-day trip, and he won’t be able to visit any place in Beijing, including PKU, on a traffic control day. Ming loves Beijing and he wants to make sure that m days can be used to visit interesting places in Beijing. So Ming made a decision:  spending k (m ≤ k ≤ n) consecutive days in Beijing is also acceptable if there are k - m traffic control days among those k days. Under this complicated situation, he doesn’t know how to make the best schedule. Please write a program to help Ming determine the best dates of the two days to visit Peking University.  Data guarantees a unique solution.

Input

There are no more than 20 test cases.

For each test case:

The first line contains two integers, above mentioned n and m (2 ≤ n ≤ 100, 2 ≤ m ≤ n).

The second line contains n integers, above mentioned p[0] , p[1] , … p[n-1]. (0 ≤ p[i] ≤ 1000, i = 0 ... n-1)

The third line is an integer q (0 ≤ q ≤ n), representing the total number of traffic control days during the n-day trip, followed by q integers representing the dates of these days.

Output

One line, including two integers a and b, representing the best dates for visiting PKU.

Sample Input

7 3
6 9 10 1 0 8 35
3 5 6 2
4 2
10 11 1 2
1 2

Sample Output

0 3
1 3

【分析】模拟题。出差n天,要拿出连续的m天出去玩,其中这m天的第一天和另一天要去北京大学。这m天中会有一些时间是交通管制日,在交通管制日是不能出去的,给出每天出去要等的每天的权值p[i],使得这两天出去p之和最小。 第一个例子是0  3 而不是3  4 是因为  如果是3  4的话,他只能玩两天,但是要玩3天的,所以选的是0  3。还要注意下标从0开始。

【代码】

#include<bits/stdc++.h>
using namespace std;

const int maxn=1010;
int p[maxn];
int vis[maxn];

int main()
{
	int n,m,a,b;
	while(~scanf("%d%d",&n,&m))
	{
		memset(vis,0,sizeof(vis));
		memset(p,0,sizeof(p));
		for(int i=0;i<n;i++)scanf("%d",&p[i]);
		int q;scanf("%d",&q);
		while(q--)
		{
			int x;scanf("%d",&x);
			vis[x]=1;
		}
		int minn=5000,k=1,t=-1;
		for(int i=0;i<n;i++)
		{
			k=1;
			if(vis[i])continue;
			int aa=p[i],bb=2000;
			for(int j=i+1;j<n;j++)
			{
				
				if(vis[j])continue;
				if(bb>p[j])
				{
					//cout<<"i="<<i<<",j="<<j<<endl;
					bb=p[j];//cout<<"bb="<<bb<<endl;
					t=j;
				}
				k++;//cout<<"k="<<k<<endl;
				if(k==m)break;
			}
			if(k<m)continue;
			if(minn>aa+bb)
			{
			//	cout<<aa<<","<<bb<<endl;
				minn=aa+bb;
				a=i;b=t;
			}
		}
		printf("%d %d\n",a,b);
	}
	return 0;
}

E - Territorial Dispute(数学几何+思维)

In 2333, the C++ Empire and the Java Republic become the most powerful country in the world. They compete with each other in the colonizing the Mars.

There are n colonies on the Mars, numbered from 1 to n. The i-th colony's location is given by a pair of integers (xi, yi). Notice that latest technology in 2333 finds out that the surface of Mars is a two-dimensional plane, and each colony can be regarded as a point on this plane. Each colony will be allocated to one of the two countries during the Mars Development Summit which will be held in the next month.

After all colonies are allocated, two countries must decide a border line. The Mars Development Convention of 2048 had declared that: A valid border line of two countries should be a straight line, which makes colonies of different countries be situated on different sides of the line.

The evil Python programmer, David, notices that there may exist a plan of allocating colonies, which makes the valid border line do not exist. According to human history, this will cause a territorial dispute, and eventually lead to war.

David wants to change the colony allocation plan secretly during the Mars Development Summit. Now he needs you to give him a specific plan of allocation which will cause a territorial dispute. He promises that he will give you 1000000007 bitcoins for the plan.

Input

The first line of the input is an integer T, the number of the test cases (T ≤ 50).

For each test case, the first line contains one integer n (1 ≤ n ≤ 100), the number of colonies.

Then n lines follow. Each line contains two integers xi, yi (0 ≤ xi, yi ≤ 1000), meaning the location of the i-th colony. There are no two colonies share the same location.

There are no more than 10 test cases with n > 10.

Output

For each test case, if there exists a plan of allocation meet David's demand, print "YES" (without quotation) in the first line, and in the next line, print a string consisting of English letters "A" and "B". The i-th character is "A" indicates that the i-th colony was allocated to C++ Empire, and "B" indicates the Java Republic.

If there are several possible solutions, you could print just one of them.

If there is no solution, print "NO".

Sample Input

2
2
0 0
0 1
4
0 0
0 1
1 0
1 1

Sample Output

NO
YES
ABBA

【分析】n≤2时,显然是NO;n=3时,其中一点在两点的连线中间是YES,否则是NO;n≥4时,因为n=4时是可以变成YES的,分两种情况,当点在另外3个点围成的三角形内部或两边相交,是YES,否则是NO。把这四个输出,剩下的随便输出就好了。

【代码】https://blog.csdn.net/axuhongbo/article/details/78074968 

#include<bits/stdc++.h>
using namespace std;

const double eps=1e-8;
double x[110],y[110];

struct point
{
    double x,y;
};
struct line
{
    point s,e;
};

int sgn(double x)
{
    if(fabs(x)<eps)return 0;
    if(x<0)return -1;
    return 1;
}
double mul(point sp,point ep,point op)
{
    return ((sp.x-op.x)*(ep.y-op.y)-(ep.x-op.x)*(sp.y-op.y));
}
bool inter(line u ,line v)
{
    return ((max(u.s.x,u.e.x)>=min(v.s.x,v.e.x))&&
            (max(v.s.x,v.e.x)>=min(u.s.x,u.e.x))&&
            (max(u.s.y,u.e.y)>=min(v.s.y,v.e.y))&&
            (max(v.s.y,v.e.y)>=min(u.s.y,u.e.y))&&
            (mul(v.s,u.e,u.s)*mul(u.e,v.e,u.s)>=0)&&
            (mul(u.s,v.e,v.s)*mul(v.e,u.e,v.s)>=0));
}
double dist(double x1,double y1,double x2,double y2)
{
    return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}
double mian(double x1,double y1,double x2,double y2,double x3,double y3)
{
    double d1,d2,d3,p;
    d1=dist(x1,y1,x2,y2);
    d2=dist(x2,y2,x3,y3);
    d3=dist(x1,y1,x3,y3);
    p=(d1+d2+d3)/2;
    return sqrt(p*(p-d1)*(p-d2)*(p-d3));
}

int main()
{
    int t;scanf("%d",&t);
    while(t--)
    {
    	int n;scanf("%d",&n);
        for(int i=0;i<n;i++)
        {
            scanf("%lf%lf",&x[i],&y[i]);
        }
        if(n<3){printf("NO\n");continue;}
        if(n==3)
        {
            if((y[1]-y[0])*(x[2]-x[0])==(x[1]-x[0])*(y[2]-y[0]))
            {
                printf("YES\n");
                double d0,d1,d2;
                d0=dist(x[1],y[1],x[2],y[2]);
                d1=dist(x[0],y[0],x[2],y[2]);
                d2=dist(x[1],y[1],x[0],y[0]);
                if(d0==d1+d2)printf("BAA\n");
                else if(d1==d0+d2)printf("ABA\n");
                else printf("AAB\n");
            }
            else printf("NO\n");
            continue;
        }
        if(n>=4)
        {
            printf("YES\n");
            if((y[1]-y[0])*(x[2]-x[0])==(x[1]-x[0])*(y[2]-y[0]))
            {
                double d0,d1,d2;
                d0=dist(x[1],y[1],x[2],y[2]);
                d1=dist(x[0],y[0],x[2],y[2]);
                d2=dist(x[1],y[1],x[0],y[0]);
                if(d0==d1+d2)printf("BAA");
                else if(d1==d0+d2)printf("ABA");
                else printf("AAB");
                for(int i=0;i<n-3;i++)printf("A");
                printf("\n");
            }
            else
            {
                double s0,s1,s2,s3;
                s3=mian(x[0],y[0],x[1],y[1],x[2],y[2]);
                s2=mian(x[0],y[0],x[1],y[1],x[3],y[3]);
                s1=mian(x[0],y[0],x[3],y[3],x[2],y[2]);
                s0=mian(x[3],y[3],x[1],y[1],x[2],y[2]);
                if(sgn(s0+s1+s2-s3)==0)printf("AAAB");
                else if(sgn(s0+s1-s2+s3)==0)printf("AABA");
                else if(sgn(s0-s1+s2+s3)==0)printf("ABAA");
                else if(sgn(s0-s1-s2-s3)==0)printf("ABBB");
                else
                {
                    point a,b,c,d;
                    a.x=x[0];
                    a.y=y[0];
                    b.x=x[1];
                    b.y=y[1];
                    c.x=x[2];
                    c.y=y[2];
                    d.x=x[3];
                    d.y=y[3];
                    line ab,ac,ad,bc,bd,cd;
                    ab.e=a;
                    ab.s=b;
                    ac.e=a;
                    ac.s=c;
                    ad.e=a;
                    ad.s=d;
                    bc.e=c;
                    bc.s=b;
                    bd.e=d;
                    bd.s=b;
                    cd.e=d;
                    cd.s=c;
                    if(inter(ab,cd))printf("AABB");
                    else if(inter(ac,bd))printf("ABAB");
                    else if(inter(ad,bc))printf("ABBA");
                }
                for(int i=0;i<n-4;i++)printf("A");
                printf("\n");
            }
        }
    }
}

F - Cake(思维)

To celebrate that WF-2018 will be held in PKU, Alice, Bob, and Cate are asked to make

N cakes.

Every cake i needs to go through 3 steps in restrict order:

1. Alice mixes flour and water for ai minutes;

2. Bob carefully bakes it for bi minutes;

3. Cate makes cream decoration for ci minutes.

Since Cate wants to have different kinds of cakes, the third step of any cake i is always not less time-consuming than the second step of any cake j. Also, it is reasonable that once anyone starts to process a cake, the procedure cannot be stopped then be resumed.

To have these cakes done as soon as possible, they need your help.

Input

There are several cases (less than 15 cases).

The first line of every case contains an integer N (1 ≤ N ≤ 105)—the number of cakes to prepare.

After that, N lines follow, each of them contains three integers ai, bi and ci (1 ≤ i ≤ N; 0 <ai, bi, ci < 106)—time that needs to be spent on the three steps of cake i respectively.

It is guaranteed that for any i and any j, bi is no greater than cj.

The input ends with N = 0.

Output

For every case, print in a single line the least possible time to make all cakes.

Sample Input

3
5 3 4
3 2 9
3 4 8
0

Sample Output

26

【题意】做一个蛋糕需要3个步骤,给出每个蛋糕的每个步骤需要的时间。规定第3个步骤用时不小于第2个步骤。且做蛋糕途中不可以有休息时间,要连续,不然就要重新做。求做完指定数目的蛋糕需要的最小时间。

【分析】是一道思维题吧,想清楚了就知道怎么做了吧大概....然鹅我还咩有想清楚,感觉做蛋糕的步骤应该有先后的,但是这个代码只是对时间进行比较选择,并没有考虑到是不是前一个步骤已经处理完.....想不通....先挂一份代码.... 分工是下面这样的~

代码:(戳这)

#include<bits/stdc++.h>
using namespace std;

#define INF 0x3f3f3f3f
#define maxn 1311000
typedef long long ll;
ll a[maxn],b[maxn],c[maxn];
 
int main()
{
    int n;
    while(scanf("%d",&n)&&n)
	{
        ll sum1=0,sum3=0;
        ll minab=INF,minbc=INF;
        for(int i=1;i<=n;i++)
		{
            scanf("%lld %lld %lld",&a[i],&b[i],&c[i]);
            
            sum1+=a[i];
            sum3+=c[i];
			
			if(minab>a[i]+b[i])minab=a[i]+b[i];
            if(minbc>b[i]+c[i])minbc=b[i]+c[i];
		}
        printf("%lld\n",max(sum1+minbc,sum3+minab));
    }
    return 0;
}

 


G - Bounce(找规律)

For Argo, it is very interesting watching a circle bouncing in a rectangle.

As shown in the figure below, the rectangle is divided into N×M grids, and the circle fits exactly one grid.

The bouncing rule is simple:

1. The circle always starts from the left upper corner and moves towards lower right.

2. If the circle touches any edge of the rectangle, it will bounce.

3. If the circle reaches any corner of the rectangle after starting, it will stop there.

Argo wants to know how many grids the circle will go through only once until it first reaches another corner. Can you help him?

Input

The input consists of multiple test cases. (Up to 105)

For each test case:

One line contains two integers N and M, indicating the number of rows and columns of the rectangle. (2 ≤ N, M ≤ 109)

Output

For each test case, output one line containing one integer, the number of grids that the circle will go through exactly once until it stops (the starting grid and the ending grid also count).

Sample Input

2 2
2 3
3 4
3 5
4 5
4 6
4 7
5 6
5 7
9 15

Sample Output

2
3
5
5
7
8
7
9
11
39

【分析】找规律(思路规律__here!

这道题光找规律找了三个小时,找出来规律之后才发现题目原来很简单。

先算出来小球一共会经过多少网格(包括重复的在内)

再算出来有多少个网格过不止一次,两者相减就可以了。

对于n*m的矩形,经过观察可以得到,小球弹跳中经过的网格总数是(n−1)×(m−1)gcd((n−1),(m−1))+1

.

可以算得 球在9*15的方格中会经过57个网格

然后又经过观察可以看出来,其实9*15的矩形(图中示意)和5*8的矩形是相似的,即5*8扩大一倍可以得到9*15的矩形。

左边是9*15的网格 右边是5*8的网格。

这两个网格中的相交点都是一样的,都是9个,而(5-2)*(8-2)正好等于9*2!

而57-9*2就是答案39.

又是经过观察,显然可以得到一个结论:交点数等于 (n-2)*(m-2)/gcd(n,m)

而只经过一次的点就是57-9*2=39.

这样我们就得到了总的公式

【代码】

#include<bits/stdc++.h>
using namespace std;

typedef long long ll;

ll gcd(ll a,ll b)
{
	return b==0?a:gcd(b,a%b);
}

int main()
{
	ll n,m;
    while(~scanf("%lld%lld",&n,&m))
    {
    	if(n==m)
    	{
    		printf("%lld\n",n);
    		continue;
		}
		else if(n>m) swap(n,m);
		ll g1=gcd(n-1,m-1);
		ll g2=((n-1)/g1)*(m-1);
		ll x=(n-1)/g1;
		ll y=(m-1)/g1;
		ll ans=g2-(x-1)*(y-1)+1;
		printf("%lld\n",ans);
	}
	return 0;
}

I - Minimum(线段树模板题)

You are given a list of integers a0, a1, …, a2^k-1.

You need to support two types of queries:

1. Output Minx,y∈[l,r] {ax∙ay}.

2. Let ax=y.

Input

The first line is an integer T, indicating the number of test cases. (1≤T≤10).

For each test case:

The first line contains an integer k (0 ≤ k ≤ 17).

The following line contains 2k integers, a0, a1, …, a2^k-1 (-2k ≤ ai < 2k).

The next line contains a integer  (1 ≤ Q < 2k), indicating the number of queries. Then next Q lines, each line is one of:

1. 1 l r: Output Minx,y∈[l,r]{ax∙ay}. (0 ≤ l ≤ r < 2k)

2. 2 x y: Let ax=y. (0 ≤ x < 2k, -2k ≤ y < 2k)

Output

For each query 1, output a line contains an integer, indicating the answer.

Sample Input

1
3
1 1 2 2 1 1 2 2
5
1 0 7
1 1 2
2 1 2
2 2 2
1 1 2

Sample Output

1
1
4

【分析】线段树模板题

【代码】https://blog.csdn.net/haut_ykc/article/details/78073915

#include<set>  
#include<map>     
#include<stack>            
#include<queue>            
#include<vector>    
#include<string> 
#include<time.h>
#include<math.h>            
#include<stdio.h>            
#include<iostream>            
#include<string.h>            
#include<stdlib.h>    
#include<algorithm>   
#include<functional>    
using namespace std;            
#define ll long long       
#define inf  1000000000000000000       
#define mod 1000000007             
#define maxn  1360100
#define lowbit(x) (x&-x)            
#define eps 1e-9
ll a[maxn*4];
ll maxs[maxn*4],mins[maxn*4];
void build(ll id,ll l,ll r)
{
	ll m;
	if(l==r)
	{
		scanf("%lld",&maxs[id]);
		mins[id]=maxs[id];
		return ;
	}
	    m=(l+r)/2;
		build(id<<1,l,m);
	    build((id<<1)+1,m+1,r);
	    maxs[id]=max(maxs[id*2],maxs[id*2+1]);
		mins[id]=min(mins[id*2],mins[id*2+1]);
}
ll query(ll id,ll l,ll r,ll L, ll R)
{
	ll ret=-inf;
	if(l<=L && r>=R)
		return maxs[id];
	ll m=(L+R)/2;
	if(l<=m)
		ret=max(ret,query(id<<1,l,r,L,m));
	if(r>m)
		ret=max(ret,query((id<<1)+1,l,r,m+1,R));
	return ret;
}
ll query1(ll id,ll l,ll r,ll L, ll R)
{
	ll ret=inf;
	if(l<=L && r>=R)
		return mins[id];
	ll m=(L+R)/2;
	if(l<=m)
		ret=min(ret,query1(id<<1,l,r,L,m));
	if(r>m)
		ret=min(ret,query1((id<<1)+1,l,r,m+1,R));
	return ret;
}
void updata(ll x,ll y,ll l,ll r,ll id)
{
	if(l==r)
	{
		maxs[id]=y;
		mins[id]=y;
		return ;
	}
	ll m=(l+r)/2;
	if(x<=m)
		updata(x,y,l,m,id*2);
	else
		updata(x,y,m+1,r,id*2+1);
	maxs[id]=max(maxs[id*2],maxs[id*2+1]);
	mins[id]=min(mins[id*2],mins[id*2+1]);
}
int  main(void)
{
	ll  n,m,i,j,T;
	ll  str;
	scanf("%lld",&T);
	while(T--)
	{
		ll b,c;
		scanf("%lld",&n);
		n=(1<<n);
		build(1,1,n);
		scanf("%lld",&m);
		for(i=1;i<=m;i++)
		{
			scanf("%lld",&str);
			scanf("%lld%lld",&b,&c);
			b++;c++;
			if(str==1)
			{
				ll ans=query1(1,b,c,1,n)*query1(1,b,c,1,n);
				ans=min(ans,query(1,b,c,1,n)*query1(1,b,c,1,n));
				ans=min(ans,query(1,b,c,1,n)*query(1,b,c,1,n));
				printf("%lld\n",ans);
			}
			else
			     c--,updata(b,c,1,n,1);
		}
	}
	return 0;
}

 

 

 

 

 

 

 

 
 
 
ACM-ICPC国际大学生程序设计竞赛)是一项全球性的大学生程序设计,每年吸引来自世界各地的顶尖大学代表队参与。ACM-ICPC竞赛的核心内容是团队编程和问题解决能力。 首先,ACM-ICPC竞赛对参选手的编程能力要求很高。参队伍需要在规定的时间内解决一系列的算法问题,这些问题常常包含复杂的数据结构和算法,要求选手在有限的时间内设计和实现高效的程序。 其次,ACM-ICPC竞赛强调团队协作。每个队伍由三名选手组成,他们需要分工合作,保持良好的沟通与协调,共同解决问题。团队成员需要相互理解、相互信任,快速地协商和决策,同时要保持高效的任务分配和时间管理。 此外,ACM-ICPC竞赛也需要选手具备良好的问题解决能力。这些问题往往是实际应用或理论推导相关的,选手需要从数学、计算机科学和算法等多个角度出发,找到最佳解决方案。在面对问题时,选手需要对问题进行分析、抽象和建模,运用各种算法和数据结构进行解决。 对于参选手来说,ACM-ICPC提供了一个学习与交流的平台。在比中,选手可以接触到不同国家和地区的优秀程序设计人才,学习他们的思维方式和编程技巧。同时,ACM-ICPC还举办了一系列的培训和研讨会,让选手有机会深入了解计算机科学和算法领域最新的研究成果。 总之,ACM-ICPC国际大学生程序设计竞赛是一个挑战性与学习性兼具的比。它要求选手具备扎实的编程技能、团队合作能力和问题解决能力。参与此竞赛不仅可以锻炼自己的编程能力,还能与全球的顶尖程序设计人才进行交流,拓宽自己的视野和思维方式。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值