用hash摘要zone,貌似能加速有点,但是也不是十分确定。
-
#include "stdafx.h"
-
-
#define MAX_MAP_SIZE 64
-
#define ZONE_SIZE 4
-
#define HASH_SZ 32
-
-
char zone[ZONE_SIZE][ZONE_SIZE];
-
int hisindex=0;
-
unsigned short hiszmap[10000][2][2];
-
-
unsigned short guess_hash[HASH_SZ][HASH_SZ];
-
-
extern void randomscan(char zone[ZONE_SIZE][ZONE_SIZE]);
-
-
unsigned short guess_to_hash(char gss[64][64],int x,int y)
-
{
-
//Use bit operation and 16 as base
-
return gss[x][y] | gss[x][y+1]<<4 | gss[x+1][y]<<8 | gss[x+1][y+1]<<12;
-
#if 0//Use 15 as base
-
return gss[x][y]+gss[x][y+1]*15+gss[x+1][y]*225+gss[x+1][y+1]*3375;
-
#endif
-
}
-
-
void zone_to_hash(char zone[4][4], unsigned short zmap[2][2])
-
{
-
//Use bit operation and 16 as base
-
zmap[0][0]=zone[0][0] | zone[0][1]<<4 | zone[1][0]<<8 | zone[1][1]<<12;
-
zmap[0][1]=zone[0][2] | zone[0][3]<<4 | zone[1][2]<<8 | zone[1][3]<<12;
-
zmap[1][0]=zone[2][0] | zone[2][1]<<4 | zone[3][0]<<8 | zone[3][1]<<12;
-
zmap[1][1]=zone[2][2] | zone[2][3]<<4 | zone[3][2]<<8 | zone[3][3]<<12;
-
-
#if 0 //Use 15 as base
-
zmap[0][0]=zone[0][0]+zone[0][1]*15+zone[1][0]*225+zone[1][1]*3375;
-
zmap[0][1]=zone[0][2]+zone[0][3]*15+zone[1][2]*225+zone[1][3]*3375;
-
zmap[1][0]=zone[2][0]+zone[2][1]*15+zone[3][0]*225+zone[3][1]*3375;
-
zmap[1][1]=zone[2][2]+zone[2][3]*15+zone[3][2]*225+zone[3][3]*3375;
-
#endif
-
}
-
-
void save_guess_info(int N,char gss[64][64])
-
{
-
int k;
-
for(k=0;k<=N-2;k+=2){
-
guess_hash[k/2][0] = guess_to_hash(gss,k,0);//第0列
-
guess_hash[0][k/2] = guess_to_hash(gss,0,k);//第0行
-
guess_hash[k/2][(N-2)/2] = guess_to_hash(gss,k,N-2);//第N-2列
-
guess_hash[(N-2)/2][k/2] = guess_to_hash(gss,N-2,k);//第N-2行
-
}
-
}
-
-
void fill_guess_by_zmap(char gss[64][64],unsigned short zmap[2][2],char x,char y)
-
{
-
char i,j;
-
char a=2*x;
-
char b=2*y;
-
for(i=0;i<2;i++){
-
for(j=0;j<2;j++){
-
//Use bit operation and 16 as base
-
gss[a+i*2][b+j*2]=zmap[i][j]&0xF;
-
gss[a+i*2][b+j*2+1]=(zmap[i][j]>>4)&0xF;
-
gss[a+i*2+1][b+j*2]=(zmap[i][j]>>8)&0xF;
-
gss[a+i*2+1][b+j*2+1]=(zmap[i][j]>>12)&0xF;
-
#if 0 //Use 15 as base
-
gss[a+i*2][b+j*2] = (zmap[i][j] - 1)%15 + 1;//这里要注意的是加1减1操作,这是mod操作的一个技巧
-
gss[a+i*2][b+j*2+1] = ((zmap[i][j]-gss[a+i*2][b+j*2])/15 - 1)%15 + 1;
-
gss[a+i*2+1][b+j*2] = ((zmap[i][j]-gss[a+i*2][b+j*2]-gss[a+i*2][b+j*2+1]*15)/225 -1 )%15 + 1;
-
gss[a+i*2+1][b+j*2+1]=((zmap[i][j]-gss[a+i*2][b+j*2]-gss[a+i*2][b+j*2+1]*15-gss[a+i*2+1][b+j*2]*225)/3375 - 1)%15 + 1;
-
#endif
-
}
-
}
-
}
-
int calc_and_upmap(int N,char gss[64][64],unsigned short zmap[2][2])
-
{
-
char i,j,x,y;
-
int inner=0;
-
int meetnum;
-
int upnum=0;//初始化为0
-
-
for(x=0;x<=N/2-2;x++){
-
for(y=0;y<=N/2-2;y++){
-
meetnum=0;
-
for(i=0;i<2;i++){
-
for(j=0;j<2;j++){
-
if(zmap[i][j]==guess_hash[x+i][y+j])
-
meetnum++;
-
}
-
}
-
if(meetnum>=2){
-
for(i=0;i<2;i++)
-
for(j=0;j<2;j++)
-
guess_hash[x+i][y+j]=zmap[i][j];
-
-
inner=1;
-
upnum=4-meetnum;
-
fill_guess_by_zmap(gss,zmap,x,y);
-
break;//找到一个匹配就要中断
-
}
-
}
-
if(inner==1)
-
break;//中断外层循环
-
}
-
return upnum;
-
}
-
-
//将random区域摘要为2x2的map
-
void save_zmap_info(unsigned short zmap[2][2])
-
{
-
int i,j;
-
for(i=0;i<2;i++){
-
for(j=0;j<2;j++){
-
hiszmap[hisindex][i][j]=zmap[i][j];
-
}
-
}
-
hisindex+=1;
-
}
-
-
int update_by_hiszmap(int N, char gss[64][64])
-
{
-
int i,j;
-
int index;
-
int upnum=0;
-
unsigned short hmap[2][2];
-
for(index=0;index<hisindex;index++){
-
for(i=0;i<2;i++){
-
for(j=0;j<2;j++){
-
hmap[i][j]=hiszmap[index][i][j];
-
}
-
}
-
upnum=calc_and_upmap(N,gss,hmap);
-
if(upnum>0)//首先要记得这里如果upnum大于0,说明已经找到匹配
-
break; //因为题目保证了只能匹配一块区域,所以这里要中断
-
}
-
return upnum;
-
}
-
-
void reconstruct(int N, char gss[MAX_MAP_SIZE][MAX_MAP_SIZE])//map=guess_map
-
{
-
int upnum;
-
int leftnum=(N-4)*(N-4)/4;
-
char zone[4][4];
-
unsigned short zmap[2][2];
-
int hisupnum;
-
int i,j;
-
for(i=0;i<32;i++){
-
for(j=0;j<32;j++){
-
guess_hash[i][j]=0;
-
}
-
}
-
save_guess_info(N,gss);
-
while(leftnum != 0){
-
randomscan(zone);
-
zone_to_hash(zone,zmap);
-
upnum=calc_and_upmap(N,gss,zmap);
-
if(upnum!=0)//有更新
-
{
-
leftnum-=upnum;//更新剩余的2x2map
-
hisupnum=0;
-
do{
-
hisupnum=update_by_hiszmap(N,gss);//用历史zmap更新
-
leftnum-=hisupnum;
-
if(leftnum==0)
-
break;
-
}while(hisupnum>0);
-
}
-
save_zmap_info(zmap);
-
}
-
hisindex=0;//每个case结束后要复位
-
}
-
#ifndef _CRT_SECURE_NO_WARNINGS
-
#define _CRT_SECURE_NO_WARNINGS
-
#endif
-
#include "stdafx.h"
-
#include <stdio.h>
-
#include <windows.h>//---
-
-
#define MAX_MAP_SIZE 64
-
#define ZONE_SIZE 4
-
-
#define MAX_SCAN_COUNT 100000
-
-
extern void reconstruct(int N, char map[MAX_MAP_SIZE][MAX_MAP_SIZE]);
-
-
static char map[MAX_MAP_SIZE][MAX_MAP_SIZE];
-
static int N;
-
static int seed;
-
static int scancount;
-
-
static int pseudo_rand() {
-
seed = seed * 214013 + 2531011;
-
return (seed >> 16) & 0x7fff;
-
}
-
-
void randomscan(char zone[ZONE_SIZE][ZONE_SIZE]) {
-
if (scancount >= MAX_SCAN_COUNT)
-
return;
-
-
int x0 = (pseudo_rand() % ((N - ZONE_SIZE)/2 + 1)) * 2; // x0 = 0, 2, 4, ..., N - 4
-
int y0 = (pseudo_rand() % ((N - ZONE_SIZE)/2 + 1)) * 2; // y0 = 0, 2, 4, ..., N - 4
-
-
for (int y = 0; y < ZONE_SIZE; ++y)
-
for (int x = 0; x < ZONE_SIZE; ++x)
-
zone[y][x] = map[y + y0][x + x0];
-
-
++scancount;
-
}
-
-
static void makemap() {
-
for (int y = 0; y < N; ++y)
-
for (int x = 0; x < N; ++x)
-
map[y][x] = pseudo_rand() % 15 + 1;
-
}
-
-
static bool compare(char map1[MAX_MAP_SIZE][MAX_MAP_SIZE], char map2[MAX_MAP_SIZE][MAX_MAP_SIZE]) {
-
for (int y = 0; y < N; ++y)
-
for (int x = 0; x < N; ++x)
-
if (map1[y][x] != map2[y][x])
-
return false;
-
-
return true;
-
}
-
-
int main() {
-
int TC, totalscore, totalscan;
-
int t;//---
-
freopen("20180310i.txt", "r", stdin);
-
-
setbuf(stdout, NULL);
-
scanf("%d", &TC);
-
t=GetTickCount();
-
totalscore = totalscan = 0;
-
for (int testcase = 1; testcase <= TC; ++testcase) {
-
char guess[MAX_MAP_SIZE][MAX_MAP_SIZE];
-
int min_scan_count;
-
-
scanf("%d %d %d", &N, &seed, &min_scan_count);
-
-
makemap();
-
-
scancount = 0;
-
-
for (int y = 0; y < N; ++y)
-
for (int x = 0; x < N; ++x)
-
guess[y][x] = 0;
-
-
for (int k = 0; k < N; ++k) {
-
guess[k][0] = map[k][0];//第0列
-
guess[0][k] = map[0][k];//第0行
-
guess[k][1] = map[k][1];//
-
guess[1][k] = map[1][k];//
-
guess[k][N - 1] = map[k][N - 1];//
-
guess[N - 1][k] = map[N - 1][k];//
-
guess[k][N - 2] = map[k][N - 2];//第N-2列
-
guess[N - 2][k] = map[N - 2][k];//第N-2行
-
}
-
-
reconstruct(N, guess);
-
-
if (!compare(map, guess))
-
scancount = MAX_SCAN_COUNT;
-
totalscan += scancount;
-
-
int score;
-
if (TC == 5) { // sample testcase
-
score = scancount < MAX_SCAN_COUNT ? 100 : 0;
-
totalscore += score;
-
} else { // eval testcase
-
score = scancount <= min_scan_count + (min_scan_count / 2) ? 100 : 0;
-
totalscore += score;
-
}
-
-
printf("#%d %d\n", testcase, score);
-
}
-
t = GetTickCount() - t;
-
if (totalscan > MAX_SCAN_COUNT) totalscan = MAX_SCAN_COUNT;
-
printf("total score = %d, total scan = %d\n", totalscore / TC, totalscan);
-
printf("used time is %d\n", t);
-
return 0;
-
}
-
/*
-
5
-
8 26585 3
-
12 24059 28
-
16 26751 50
-
20 19164 100
-
24 10446 153
-
*/
阅读(1534) | 评论(1) | 转发(0) |