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;
}
 
 
 

猜你喜欢

转载自blog.csdn.net/qq_38735931/article/details/83830963