Google Kickstart 2017 Round A 题解

打得最惨的一场google线上比赛。

ABC三题,代码见最后


Problem A. Square Counting

This contest is open for practice. You can try every problem as many times as you like, though we won't keep track of which problems you solve. Read the Quick-Start Guide to get started.
Small input
8 points
Large input
17 points

Problem

Mr. Panda has recently fallen in love with a new game called Square Off, in which players compete to find as many different squares as possible on an evenly spaced rectangular grid of dots. To find a square, a player must identify four dots that form the vertices of a square. Each side of the square must have the same length, of course, but it does not matter what that length is, and the square does not necessarily need to be aligned with the axes of the grid. The player earns one point for every different square found in this way. Two squares are different if and only if their sets of four dots are different.

Mr. Panda has just been given a grid with R rows and C columns of dots. How many different squares can he find in this grid? Since the number might be very large, please output the answer modulo 109 + 7 (1000000007).

Input

The first line of the input gives the number of test cases, TT lines follow. Each line has two integers R and C: the number of dots in each row and column of the grid, respectively.

Output

For each test case, output one line containing Case #x: y, where x is the test case number (starting from 1) and y is the number of different squares can be found in the grid.

Limits

1 ≤ T ≤ 100.

Small dataset

2 ≤ R ≤ 1000.
2 ≤ C ≤ 1000.

Large dataset

2 ≤ R ≤ 109.
2 ≤ C ≤ 109.

Sample


Input 
 

Output 
 
4
2 4
3 4
4 4
1000 500

Case #1: 3
Case #2: 10
Case #3: 20
Case #4: 624937395

The pictures below illustrate the grids from the three sample cases and a valid square in the third sample case.






题目大意:给你一个n*m的点阵,问你这些点能组成多少个正方形


首先我们考虑答案是怎么求得的。因为要求组成正方形,所以可以发现,正方形在竖直和水平方向上所占用的格点长度是一致的。

那么我们枚举所占用的格点长度x,对于每个x,一共有x种划线方法来占满这x*x的点阵来组成新的正方形。所以我们所求的就是∑(m-i)*(n-i)*i,i为1到min(n,m)

那么这个的复杂度就是O(min(n,m))了。但是大小有10^9。于是我们考虑将各个括号展开并且合并同类项

可以得出ans=(1+2+……+(n-1))*(nm)+(1^2+2^2+……(n-1)n^2)*(n+m)+(1^3+2^3+……+(n-1)^3)=nm*n(n-1)/2+(n+m)(n-1)n(2n-1)/6+n(n-1)n(n-1)/4

这个直接计算即可

Problem B. Patterns Overlap

This contest is open for practice. You can try every problem as many times as you like, though we won't keep track of which problems you solve. Read the Quick-Start Guide to get started.
Small input
13 points
Large input
22 points

Problem

Alice likes reading and buys a lot of books. She stores her books in two boxes; each box is labeled with a pattern that matches the titles of all of the books stored in that box. A pattern consists of only uppercase/lowercase English alphabet letters and stars (*). A star can match between zero and four letters. For example, books with the titles GoneGirl andGoneTomorrow can be put in a box with the pattern Gone**, but books with the titlesTheGoneGirl, and GoneWithTheWind cannot.

Alice is wondering whether there is any book that could be stored in either of the boxes. That is, she wonders if there is a title that matches both boxes' patterns.

Input

The first line of the input gives the number of test cases, TT test cases follow. Each consists of two lines; each line has one string in which each character is either an uppercase/lowercase English letter or *.

Output

For each test case, output one line containing Case #x: y, where x is the test case number (starting from 1) and y is TRUE if there is a string that matches both patterns, orFALSE if not.

Limits

1 ≤ T ≤ 50.

Small dataset

1 ≤ the length of each pattern ≤ 200.
Each pattern contains at most 5 stars.

Large dataset

1 ≤ the length of each pattern ≤ 2000.

Sample


Input 
 

Output 
 
3
****
It
Shakes*e
S*speare
Shakes*e
*peare

Case #1: TRUE
Case #2: TRUE
Case #3: FALSE


In sample case #1, the title It matches both patterns. Note that it is possible for a * to match zero characters.

In sample case #2, the title Shakespeare matches both patterns.

In sample case #3, there is no title that matches both patterns. Shakespeare, for example, does not work because the * at the start of the *peare pattern cannot match six letters.

给你两个字符串,每个串中含有若干*,每个*可以代表0到4个字符。问通过调整*所代表的字符,可否使得两个串相等

首先第一反应就是fij表示上面匹配到第i位下面匹配到第j位的时候是否可行。先不考虑*可以为空,那么转移就是对于A串中的*,若在第i个位置,fij从f(i-1,j)到f(i-1,j-4)若有一个是可行的则可行。在B串中的*同理。若两个串当前位都是*,那么分别扫描即可

但是*可以表示为空,那么我们只需要每次往前找4个非空字符来转移即可

P.S 也可以将*拆成四个?,每个表示可以为1个字符或者空,然后直接转移即可

Problem C. Space Cubes

This contest is open for practice. You can try every problem as many times as you like, though we won't keep track of which problems you solve. Read the Quick-Start Guide to get started.
Small input
14 points
Large input
26 points
Judge's response for last submission: Correct.

Problem

"Look at the stars, look how they shine for you." - Coldplay, "Yellow"

In a galaxy far, far away, there are many stars. Each one is a sphere with a certain position (in three-dimensional space) and radius. It is possible for stars to overlap each other.

The stars are so incredibly beautiful to you that you want to capture them forever! You would like to build two cubes of the same integer edge length, and place them in space such that for each star, there is at least one cube that completely contains it. (It's not enough for a star to be completely contained by the union of the two cubes.) A star is completely contained by a cube if no point on the star is outside the cube; a point exactly on a cube face is still considered to be inside the cube.

The cubes can be placed anywhere in space, but they must be placed with their edges parallel to the coordinate axes. It is acceptable for the cubes to overlap stars or each other.

What is the minimum integer edge length that allows you to achieve this goal?

Input

The input starts with one line containing exactly one integer T, which is the number of test cases. T test cases follow.

Each test case begins with a line containing an integer, N, representing the number of stars.

This is followed by N lines. On the ith line, there are 4 space-separated integers, XiYiZiand Ri, indicating the (X, Y, Z) coordinates of the center of the ith star, and the radius of the ith star.

Output

For each test case, output one line containing Case #x: y, where x is the test case number (starting from 1) and y is the minimum cube edge length that solves the problem, as described above.

Limits

1 ≤  T ≤ 100.
-10 8 ≤  Xi ≤ 10 8, for all i.
-10 8 ≤  Yi ≤ 10 8, for all i.
-10 8 ≤  Zi ≤ 10 8, for all i.
1 ≤  Ri ≤ 10 8, for all i.
Small dataset
1 ≤  N ≤ 16.
Large dataset
1 ≤  N ≤ 2000.

Sample


Input 
 

Output 
 
3
3
1 1 1 1
2 2 2 1
4 4 4 1
3
1 1 1 2
2 3 4 1
5 6 7 1
3
1 1 1 1
1 1 1 1
9 9 9 1

Case #1: 3
Case #2: 5
Case #3: 2

In the first test case, one solution is to place two cubes with an edge length of 3 such that their corners with minimum (x, y, z) coordinates are at (0, 0, 0) and (3, 3, 3).
In the second test case, one solution is to place two cubes with an edge length of 5 such that their corners with minimum (x, y, z) coordinates are at (-1, -1, -1) and (1, 2, 3).

给你若干个星球,每个星球在(x,y,z),半径为r

现在让你用两个边长为r的正方体来覆盖,要求每个星球都至少被一个正方体完全包含

问r的最小值


分别考虑x,y,z的最小值,最优解肯定至少有一个立方体边界由这三个最小值确定

又因为有三个最小值只有两个正方体,所以至少有一个正方体的边界是由两个最小值确定的

那么我们枚举哪两维确定,然后枚举剩下一维的起点。再二分边长r贪心验证是否可行即可

复杂度O(n^2logn)


下面贴下代码

A:

#include<cstdio>
#include<algorithm>
using namespace std;
long long mod=1000000007;
inline long long power(long long x,long long y)
{
	long long t=1;
	while(y!=0)
	{
		if(y%2==1)
			t=t*x%mod;
		x=x*x%mod;
		y/=2;
	}
	return t;
}
int main()
{
	freopen("A-large.in","r",stdin);
	freopen("A-large.out","w",stdout);
	int T,k=0;
	scanf("%d",&T);
	while(T>0)
	{
		k++;
		T--;
		long long n,m;
		scanf("%lld%lld",&n,&m);
		int i;
		long long ans=0;
		if(n>m)
		{
			long long t=n;
			n=m;
			m=t;
		}
		long long xt1=(n-1LL);
		if(xt1%2==0)
		{
			xt1=xt1/2LL*n;
			xt1%=mod;
		}
		else
		{
			xt1=xt1*(n/2LL);
			xt1%=mod;
		}
		long long xt2=n*(n-1LL);
		xt2%=mod;
		xt2*=(2LL*(n-1LL)+1LL);
		xt2%=mod;
		xt2=xt2*power(6,mod-2)%mod;
		long long xt3=xt1*xt1;
		xt3%=mod;
	//	xt3=xt3*power(4,mod-2)%mod;
		ans=xt1*(n*m%mod)%mod-xt2*(n+m)%mod+xt3;
		ans%=mod;
		if(ans<0)
			ans+=mod;
	    printf("Case #%d: %lld\n",k,ans);
	}
	return 0;
}


B:

#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
bool f[2011][2011];
bool f1[2011][2011];
int main()
{
	freopen("B-large-practice.in","r",stdin);
	freopen("B-large-practice.out","w",stdout);
	int T,k=0;
	scanf("%d",&T);
	while(T>0)
	{
		string x1,x2;
		cin>>x1>>x2; 
		x1="A"+x1; 
		x2="A"+x2;
		k++;
		T--;
		int i,j,p,q;
		int lx1=x1.size(),lx2=x2.size();
		memset(f,false,sizeof(f));
		f[0][0]=true;
		for(i=1;i<=lx1;i++)
		{
			for(j=1;j<=lx2;j++)
			{
				if(i==0&&j==0)
					continue;
				if(x1[i-1]=='*')
				{
					if(x2[j-1]=='*')
					{
				/*		for(p=0;p<=4;p++)
						{
							for(q=0;q<=4;q++)
								f[i][j]=f[i][j]||f[max(i-p,0)][max(j-q,0)];
						}*/        
					//	f[i][j]=f[i-1][j-1];
						//f[i][j]=f[i-1][j]||f[i-1][max(j-1,0)]||f[i-1][max(j-2,0)]||f[i-1][max(j-3,0)]||f[i-1][max(j-4,0)];
						//f[i][j]=f[i][j]||f[i-1][j-1]||f[max(i-2,0)][j-1]||f[max(i-3,0)][j-1]||f[max(i-4,0)][j-1]||f[i][j-1];
						int lim=j-4;
						for(p=j;p>=max(lim,0);p--)
						{
							f[i][j]=f[i][j]||f[i-1][p];
							if(p>=1&&x2[p-1]=='*')
								lim--;
						}
						 lim=i-4;
						for(p=i;p>=max(lim,0);p--)
						{
							f[i][j]=f[i][j]||f[p][j-1];
							if(p>=1&&x1[p-1]=='*')
								lim--;
						}
					}
					else
					{
					//	f[i][j]=f[i-1][j]||f[i-1][max(j-1,0)]||f[i-1][max(j-2,0)]||f[i-1][max(j-3,0)]||f[i-1][max(j-4,0)];
						int lim=j-4;
						for(p=j;p>=max(lim,0);p--)
						{
							f[i][j]=f[i][j]||f[i-1][p];
							if(p>=1&&x2[p-1]=='*')
								lim--;
						}
					}
				}
				else if(x2[j-1]=='*')
				{
				//	f[i][j]=f[i-1][j-1]||f[max(i-2,0)][j-1]||f[max(i-3,0)][j-1]||f[max(i-4,0)][j-1]||f[i][j-1];
						int lim=i-4;
						for(p=i;p>=max(lim,0);p--)
						{
							f[i][j]=f[i][j]||f[p][j-1];
							if(p>=1&&x1[p-1]=='*')
								lim--;
						}
				}
				else
				{
					if(x1[i-1]==x2[j-1])
						f[i][j]=f[i-1][j-1];
					else
						f[i][j]=false;
				}
			}
		}
		if(f[lx1][lx2])
	    	printf("Case #%d: TRUE\n",k);
	    else
	    	printf("Case #%d: FALSE\n",k);
	}
	return 0;
}

C:

#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
int b[10001];
struct star
{
	int x[4],r;
}a[10001];
int x[4];
star maxx,minn;
star mi1,mi2,ma1,ma2;
int n;
inline bool check(int p1,int p2,int px,int lim)
{
	mi1=mi2=minn;
	ma1=ma2=maxx;
	int p=6-p1-p2;
	int d=a[px].x[p]-a[px].r;
	int i;
	for(i=1;i<=n;i++)
	{
		if(a[i].x[p1]+a[i].r-x[p1]<=lim&&a[i].x[p2]+a[i].r-x[p2]<=lim&&a[i].x[p]+a[i].r-d<=lim&&a[i].x[p]-a[i].r-d>=0)
		{
			//maxx=
		}
		else
		{
			mi2.x[1]=min(mi2.x[1],a[i].x[1]-a[i].r);
			mi2.x[2]=min(mi2.x[2],a[i].x[2]-a[i].r);
			mi2.x[3]=min(mi2.x[3],a[i].x[3]-a[i].r);
			ma2.x[1]=max(ma2.x[1],a[i].x[1]+a[i].r);
			ma2.x[2]=max(ma2.x[2],a[i].x[2]+a[i].r);
			ma2.x[3]=max(ma2.x[3],a[i].x[3]+a[i].r);
		}
	}
	int xt=max(max(ma2.x[1]-mi2.x[1],ma2.x[2]-mi2.x[2]),ma2.x[3]-mi2.x[3]);
	if(xt<=lim)
		return true;
	return false;
}
int main()
{
	freopen("C-large-practice.in","r",stdin);
	freopen("C-large-practice.out","w",stdout);
	maxx.x[1]=maxx.x[2]=maxx.x[3]=-300000000;
	minn.x[1]=minn.x[2]=minn.x[3]=300000000;
	int T,kk=0;
	scanf("%d",&T);
	while(T>0)
	{
		kk++;
		T--;
		scanf("%d",&n); 
		int i,j,k;
		x[1]=x[2]=x[3]=1000000000;
		for(i=1;i<=n;i++)
		{
			scanf("%d%d%d%d",&a[i].x[1],&a[i].x[2],&a[i].x[3],&a[i].r);
			x[1]=min(x[1],a[i].x[1]-a[i].r);
			x[2]=min(x[2],a[i].x[2]-a[i].r);
			x[3]=min(x[3],a[i].x[3]-a[i].r);
		}
		int ans=2100000000;
		for(i=1;i<=2;i++)
		{
			for(j=i+1;j<=3;j++)
			{
				for(k=1;k<=n;k++)
				{
					int l=1,r=500000000;
					while(l<=r)
					{
						int mid=(l+r)/2;
						if(check(i,j,k,mid))
							r=mid-1;
						else
							l=mid+1;
					}
					ans=min(ans,l); 
				}
			}
		}
	    printf("Case #%d: %d\n",kk,ans);
	}
	return 0;
}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值