好久没在正式的比赛中做div1了……感觉还好吧。
Problem A
第一题不解释,如果n为偶数肯定-1了,n为奇数好像有好多好多种搞法。
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
int main()
{
int i,j,n;
scanf("%d",&n);
if (n%2==0)
{
printf("-1\n");
return 0;
}
for (i=0;i<n-1;i++)
{
printf("%d ",i);
}
printf("%d\n",i);
for (i=0;i<n-1;i++)
{
printf("%d ",i);
}
printf("%d\n",i);
for (i=0;i<n-1;i++)
{
printf("%d ",(i+i)%n);
}
printf("%d\n",(i+i)%n);
return 0;
}
Problem B
先求出最大的矩形的长宽,然后求出以给定的点为中心或者离中心最近且字典序最小的矩形,然后再把他移到大矩形之内就好了。
水题。
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
int gcd(int x,int y)
{
return y==0?x:gcd(y,x%y);
}
int main()
{
int i,j,n,x,y,a,b,x1,y1,x2,y2,m,tmp,xx,yy;
scanf("%d%d%d%d%d%d",&n,&m,&x,&y,&a,&b);
tmp=gcd(a,b);
a=a/tmp;
b=b/tmp;
tmp=min(n/a,m/b);
xx=a*tmp;
yy=b*tmp;
if (xx%2==0)
{
x1=x-xx/2;
x2=x+xx/2;
}
else
{
x1=x-xx/2-1;
x2=x+xx/2;
}
if (yy%2==0)
{
y1=y-yy/2;
y2=y+yy/2;
}
else
{
y1=y-yy/2-1;
y2=y+yy/2;
}
if (x1<0)
{
x2+=(-x1);
x1=0;
}
if (y1<0)
{
y2+=(-y1);
y1=0;
}
if (x2>n)
{
x1-=(x2-n);
x2=n;
}
if (y2>m)
{
y1-=(y2-m);
y2=m;
}
printf("%d %d %d %d\n",x1,y1,x2,y2);
return 0;
}
Problem C
由于两个数如果对m余数相同,则m一定可以被abs(a-b)整除。
所以,先求出所有的abs(a_i, a_j)的值。
然后计算出对于任意m,有多少组a和b能够被m除余数相同。
之后就从小枚举m到大看看是不是去掉k个数后能满足条件。
对于k=0 余数相同的组数必须是0
k=1,余数相同的组数必须是1
k=2,两种情况,一种是(a,b)(c,d) 一种是(a,b)(b,c)(a,c),所以需要特别判断一下,求出所有的数对m取余相同的有几个,再判定就可以了。
对k=3和4同理。
比赛的时候没有考虑到只有一个数的情况,WA了。。可惜。
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
int a[1000005];
int num[1000005];
int vis[1000005];
int main()
{
int i,j,n,maxn,k;
scanf("%d%d",&n,&k);
for (i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
if (n==1)
{
printf("1\n");
return 0;
}
memset(num,0,sizeof(num));
maxn=0;
for (i=0;i<n;i++)
{
for (j=i+1;j<n;j++)
{
num[abs(a[i]-a[j])]++;
maxn=max(maxn,abs(a[i]-a[j]));
}
}
for (i=1;i<=maxn;i++)
{
for (j=i*2;j<=maxn;j+=i)
{
num[i]+=num[j];
}
}
for (i=1;i<=maxn;i++)
{
if (num[i]>k*(k+1)/2) continue;
if (num[i]<=k)
{
printf("%d\n",i);
break;
}
memset(vis,0,sizeof(vis));
int cnt=0;
for (j=0;j<n;j++)
{
if (vis[a[j]%i]==1) cnt++;
else vis[a[j]%i]++;
if (cnt>k) break;
}
if (j==n)
{
printf("%d\n",i);
break;
}
}
return 0;
}