div1难度的挑战赛属实难顶,只能勉强做两题。
A题比较简单,优先塞2,如果有空余就补1。
本来一开始还在慢悠悠的一次一次塞,后来发现数据太大了,改了下算法。
#include<stdio.h>
int main()
{
int t;
scanf("%d",&t);
long long add,m,n,k,s,temp,temp2;
while(t--)
{
s=0;
scanf("%lld %lld %lld",&m,&n,&k);
s+=(n/(k/2));
//printf("%d ",s);
m-=(k%2)*s;
//printf("%d ",m);
n-=(k/2)*s;
//printf("%d ",n);
if(m>0||n>0)
{
s++;
m-=(k-2*n);
//printf("%d ",m);
n=0;
}
if(m>0)
{
s+=m/k;
if(m%k!=0)
s++;
}
printf("%lld\n",s-1);
}
return 0;
} B题给定a,b,构造一个有a割点b桥的无自环、无重边、连通图。
不难,就是特别烦。分四种情况:1.ab均为0,输出一个三角形即可。2.a为0时b>2,此时无解。3.a>1时b为0,输出若干四边形(形如[1 2],[1 3],[2 4],[3 4],[4 5],[4 6],[4 7],[4 8],这样4就是一个割点,看起来像是用4连接起来两个四边形)。
4.a>1,b>1。先记录一下a和b谁更大,然后构造形如[4 5],[5 6],[6 7]这样的图,这时候割点和桥数量相当,直至割点耗尽或桥耗尽。
如果还剩割点,就接着画四边形。如果还剩桥,就在4处构造额外的桥,因为4本身是割点,所以这时候构造桥不需要加割点。
没注意到a和b导致输入的时候顺序反了下。注意点的数量一定要和构造出的相同,不然会有孤立的点导致不连通。边的数量也要正确,否则会输出不正确。因为边数的问题wa了很多次。
2020/6/23更新:这做法属实笨。实际上桥和割点可以分开构造,会简洁和方便很多。
#include<stdio.h>
int main()
{
int add,add2,S,a,b;
scanf("%d %d",&b,&a);
S=0;
if(b==0&&a==0)
{
printf("3 3\n1 2\n2 3\n3 1\n");
return 0;
}
if(a>1&&b==0)
{
printf("-1");
return 0;
}
if(a==0&&b>0)
{
printf("%d %d\n",b*3+4,(b+1)*4);
for(add2=0;add2<=b;add2++)
{
printf("%d %d\n%d %d\n%d %d\n%d %d\n",
add2*3+1,add2*3+2,add2*3+1,add2*3+3,
add2*3+2,add2*3+4,add2*3+3,add2*3+4);
}
return 0;
}
/*if(a==1&&b>1)
{
printf("%d %d\n",b+1,b);
for(add2=2;add2<=b+1;add2++)
printf("1 %d\n",add2);
return 0;
}*/
if(b<a-1)
{
S=a-b-1;
}
if(b==a-1)
{
printf("%d %d\n",a+1,a);
for(add=1;add<=a;add++)
printf("%d %d\n",add,add+1);
return 0;
}
if(S>0)
{
printf("%d %d\n",b+4+(-1)*3+3+S+1,4*0+4+a);
a=b;
}
else
printf("%d %d\n",a+4+(b-a-1)*3+3,4*(b-a)+4+a+S);
printf("1 2\n1 3\n2 4\n3 4\n");
if(S>0)
for(add2=1;add2<=S+1;add2++)
{
printf("4 %d\n",a+4+(-1)*3+3+add2);
}
for(add=1;add<=a;add++)
{
printf("%d %d\n",add+3,add+4);
}
//最后的点是a+4 ,=add+2
for(add=a+4,add2=0;add2<=b-a-1;add2++)
{
printf("%d %d\n%d %d\n%d %d\n%d %d\n",
add+add2*3,add+add2*3+1,add+add2*3,add+add2*3+2,
add+add2*3+1,add+add2*3+3,add+add2*3+2,add+add2*3+3);
}
return 0;
}
京公网安备 11010502036488号