在达尔的指导下,第一次做了这类比赛,
在 Observers 里面的成绩:
CHN | Chuanshun Yuan | 833 | * | * | * | * | * | * | * | * | x | * | * | * | * | * | * | * | * | * | * | * | * | x | x | x | * | x | * | * | * | * |
A题,莫名其妙地第9个数据挂,还是没有弄清为啥错了。其实A题还是有些值得说的,
首先,标程的分析中认为排序后先把小的部分累加,那么最后不能加的那个用做是否使用打折扣?为什么可以这样,我也纳闷。
其次,达尔戈说的一次排序(O(nlogn))后,枚举每个cow( O(n) )使用打折扣,然后是对每个枚举到的要统计一个和来逼近S,显然这里是二分可以快速完成,所以总的时间复杂度O( nlog(n) ),即使n<=10^6也是可以做的,何况题目n<=1000;
B题,线段树直接写,达尔说 “铜赛这水平的还要用线段树么”,反正我是直接写的,有标记延迟,最后一个所有节点的递归得到最终的值。
C题,这种题最不会了,而且犯浑了一下,我是枚举第一头牛到达中点的情况,再验证第二头牛是否能在指定条件下到达中点,挂得很惨。。。
标程的分析:
A much simpler way to look at this problem is to simply countall possible self-avoiding walks from (1,1) to (5,5) that cover all the valid squares.That is, we pretend that there is just one cow who wants to move from (1,1) to (5,5),instead of there being two cows moving at the same time. It is easy to see that thereis a one-to-one correspondence between paths involving two cows meeting halfway (as in the original problem statement) and paths involving just one cow who starts at (1,1)and ends at (5,5); the midpoint of the one-cow path would correspond to the meetingpoint in the analogous two-cow solution.
Now that we know we need to count paths from (1,1) to (5,5), we proceed to enumerateand count all such paths with a recursive function. The "count" function below does thisby temporarily noting that the current square
is blocked (so we don't return there),temporarily incrementing the blocked square count K, and then recursively visiting allneighbors, accumulating the counts we get from each of them.
也即,根据题目需求,可以等价于使第一头牛从(1,1)到(5,5)走一遍的路的总数,而且标程写的十分nb,我从来没有见过这种写法。果断学习之
【C题标程】
#include <cstdio>
#include <cmath>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define MM(a,b) memset(a,b,sizeof(a));
typedef unsigned long long u64;
typedef long long lld;
#define maxn
bool map[10][10];
int K;
int count(int x,int y){
int c;
if(x<0||x>4||y<0||y>4||map[x][y]!=0) return 0;
map[x][y]=1;
K++;
if( K==25 && x==4 && y==4 ) c=1;
else
c= count(x-1,y)+count(x+1,y)+count(x,y-1)+count(x,y+1);
map[x][y]=0;
K--;
return c;
}
int main()
{
while(cin>>K){
MM( map, 0 );
for(int i=0;i<K;++i){
int x,y;
scanf("%d%d",&x,&y);
map[x-1][y-1]=1;
}
int ans= count(0,0);
printf("%d\n",ans);
}
}