Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1545161
  • 博文数量: 327
  • 博客积分: 10000
  • 博客等级: 上将
  • 技术积分: 3556
  • 用 户 组: 普通用户
  • 注册时间: 2005-04-05 21:28
个人简介

东黑布衣,流浪幽燕。 真诚善良,值得信赖。

文章分类

全部博文(327)

我的朋友

分类: BSD

2018-03-27 15:03:37

用hash摘要zone,貌似能加速有点,但是也不是十分确定。

  1. #include "stdafx.h"

  2. #define MAX_MAP_SIZE 64
  3. #define ZONE_SIZE 4
  4. #define HASH_SZ 32

  5. char zone[ZONE_SIZE][ZONE_SIZE];
  6. int hisindex=0;
  7. unsigned short hiszmap[10000][2][2];

  8. unsigned short guess_hash[HASH_SZ][HASH_SZ];

  9. extern void randomscan(char zone[ZONE_SIZE][ZONE_SIZE]);

  10. unsigned short guess_to_hash(char gss[64][64],int x,int y)
  11. {
  12.      //Use bit operation and 16 as base
  13.    return gss[x][y] | gss[x][y+1]<<4 | gss[x+1][y]<<8 | gss[x+1][y+1]<<12;
  14. #if 0//Use 15 as base
  15.    return gss[x][y]+gss[x][y+1]*15+gss[x+1][y]*225+gss[x+1][y+1]*3375;
  16. #endif
  17. }

  18. void zone_to_hash(char zone[4][4], unsigned short zmap[2][2])
  19. {
  20.    //Use bit operation and 16 as base
  21.    zmap[0][0]=zone[0][0] | zone[0][1]<<4 | zone[1][0]<<8 | zone[1][1]<<12;
  22.    zmap[0][1]=zone[0][2] | zone[0][3]<<4 | zone[1][2]<<8 | zone[1][3]<<12;
  23.    zmap[1][0]=zone[2][0] | zone[2][1]<<4 | zone[3][0]<<8 | zone[3][1]<<12;
  24.    zmap[1][1]=zone[2][2] | zone[2][3]<<4 | zone[3][2]<<8 | zone[3][3]<<12;

  25. #if 0 //Use 15 as base
  26.    zmap[0][0]=zone[0][0]+zone[0][1]*15+zone[1][0]*225+zone[1][1]*3375;
  27.    zmap[0][1]=zone[0][2]+zone[0][3]*15+zone[1][2]*225+zone[1][3]*3375;
  28.    zmap[1][0]=zone[2][0]+zone[2][1]*15+zone[3][0]*225+zone[3][1]*3375;
  29.    zmap[1][1]=zone[2][2]+zone[2][3]*15+zone[3][2]*225+zone[3][3]*3375;
  30. #endif
  31. }

  32. void save_guess_info(int N,char gss[64][64])
  33. {
  34.    int k;
  35.    for(k=0;k<=N-2;k+=2){
  36.       guess_hash[k/2][0] = guess_to_hash(gss,k,0);//第0列
  37.       guess_hash[0][k/2] = guess_to_hash(gss,0,k);//第0行
  38.       guess_hash[k/2][(N-2)/2] = guess_to_hash(gss,k,N-2);//第N-2列
  39.       guess_hash[(N-2)/2][k/2] = guess_to_hash(gss,N-2,k);//第N-2行
  40.    }
  41. }

  42. void fill_guess_by_zmap(char gss[64][64],unsigned short zmap[2][2],char x,char y)
  43. {
  44.    char i,j;
  45.    char a=2*x;
  46.    char b=2*y;
  47.    for(i=0;i<2;i++){
  48.       for(j=0;j<2;j++){
  49.          //Use bit operation and 16 as base
  50.             gss[a+i*2][b+j*2]=zmap[i][j]&0xF;
  51.             gss[a+i*2][b+j*2+1]=(zmap[i][j]>>4)&0xF;
  52.          gss[a+i*2+1][b+j*2]=(zmap[i][j]>>8)&0xF;
  53.             gss[a+i*2+1][b+j*2+1]=(zmap[i][j]>>12)&0xF;
  54. #if 0 //Use 15 as base
  55.          gss[a+i*2][b+j*2] = (zmap[i][j] - 1)%15 + 1;//这里要注意的是加1减1操作,这是mod操作的一个技巧
  56.          gss[a+i*2][b+j*2+1] = ((zmap[i][j]-gss[a+i*2][b+j*2])/15 - 1)%15 + 1;
  57.          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;
  58.          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;
  59. #endif
  60.         }
  61.     }
  62. }
  63. int calc_and_upmap(int N,char gss[64][64],unsigned short zmap[2][2])
  64. {
  65.    char i,j,x,y;
  66.    int inner=0;
  67.    int meetnum;
  68.    int upnum=0;//初始化为0
  69.    
  70.    for(x=0;x<=N/2-2;x++){
  71.       for(y=0;y<=N/2-2;y++){
  72.          meetnum=0;
  73.          for(i=0;i<2;i++){
  74.             for(j=0;j<2;j++){
  75.                if(zmap[i][j]==guess_hash[x+i][y+j])
  76.                   meetnum++;
  77.             }
  78.          }
  79.          if(meetnum>=2){
  80.             for(i=0;i<2;i++)
  81.             for(j=0;j<2;j++)
  82.                guess_hash[x+i][y+j]=zmap[i][j];

  83.             inner=1;
  84.             upnum=4-meetnum;
  85.             fill_guess_by_zmap(gss,zmap,x,y);
  86.             break;//找到一个匹配就要中断
  87.          }
  88.       }
  89.       if(inner==1)
  90.          break;//中断外层循环
  91.    }
  92.    return upnum;
  93. }

  94. //将random区域摘要为2x2的map
  95. void save_zmap_info(unsigned short zmap[2][2])
  96. {
  97.    int i,j;
  98.    for(i=0;i<2;i++){
  99.       for(j=0;j<2;j++){
  100.          hiszmap[hisindex][i][j]=zmap[i][j];
  101.       }
  102.    }
  103.    hisindex+=1;
  104. }

  105. int update_by_hiszmap(int N, char gss[64][64])
  106. {
  107.    int i,j;
  108.    int index;
  109.    int upnum=0;
  110.    unsigned short hmap[2][2];
  111.    for(index=0;index<hisindex;index++){
  112.       for(i=0;i<2;i++){
  113.          for(j=0;j<2;j++){
  114.             hmap[i][j]=hiszmap[index][i][j];
  115.          }
  116.       }
  117.       upnum=calc_and_upmap(N,gss,hmap);
  118.       if(upnum>0)//首先要记得这里如果upnum大于0,说明已经找到匹配
  119.          break; //因为题目保证了只能匹配一块区域,所以这里要中断
  120.    }
  121.    return upnum;
  122. }

  123. void reconstruct(int N, char gss[MAX_MAP_SIZE][MAX_MAP_SIZE])//map=guess_map
  124. {
  125.    int upnum;
  126.    int leftnum=(N-4)*(N-4)/4;
  127.    char zone[4][4];
  128.    unsigned short zmap[2][2];
  129.    int hisupnum;
  130.    int i,j;
  131.    for(i=0;i<32;i++){
  132.       for(j=0;j<32;j++){
  133.          guess_hash[i][j]=0;
  134.       }
  135.    }
  136.    save_guess_info(N,gss);
  137.    while(leftnum != 0){
  138.       randomscan(zone);
  139.       zone_to_hash(zone,zmap);
  140.       upnum=calc_and_upmap(N,gss,zmap);
  141.       if(upnum!=0)//有更新
  142.       {
  143.          leftnum-=upnum;//更新剩余的2x2map
  144.          hisupnum=0;
  145.          do{
  146.             hisupnum=update_by_hiszmap(N,gss);//用历史zmap更新
  147.             leftnum-=hisupnum;
  148.                 if(leftnum==0)
  149.                     break;
  150.          }while(hisupnum>0);
  151.       }
  152.       save_zmap_info(zmap);
  153.    }
  154.    hisindex=0;//每个case结束后要复位
  155. }

  1. #ifndef _CRT_SECURE_NO_WARNINGS
  2. #define _CRT_SECURE_NO_WARNINGS
  3. #endif
  4. #include "stdafx.h"
  5. #include <stdio.h>
  6. #include <windows.h>//---

  7. #define MAX_MAP_SIZE 64
  8. #define ZONE_SIZE 4

  9. #define MAX_SCAN_COUNT 100000

  10. extern void reconstruct(int N, char map[MAX_MAP_SIZE][MAX_MAP_SIZE]);

  11. static char map[MAX_MAP_SIZE][MAX_MAP_SIZE];
  12. static int N;
  13. static int seed;
  14. static int scancount;

  15. static int pseudo_rand() {
  16.    seed = seed * 214013 + 2531011;
  17.    return (seed >> 16) & 0x7fff;
  18. }

  19. void randomscan(char zone[ZONE_SIZE][ZONE_SIZE]) {
  20.    if (scancount >= MAX_SCAN_COUNT)
  21.       return;

  22.    int x0 = (pseudo_rand() % ((N - ZONE_SIZE)/2 + 1)) * 2; // x0 = 0, 2, 4, ..., N - 4
  23.    int y0 = (pseudo_rand() % ((N - ZONE_SIZE)/2 + 1)) * 2; // y0 = 0, 2, 4, ..., N - 4

  24.    for (int y = 0; y < ZONE_SIZE; ++y)
  25.    for (int x = 0; x < ZONE_SIZE; ++x)
  26.       zone[y][x] = map[y + y0][x + x0];

  27.    ++scancount;
  28. }

  29. static void makemap() {
  30.    for (int y = 0; y < N; ++y)
  31.    for (int x = 0; x < N; ++x)
  32.       map[y][x] = pseudo_rand() % 15 + 1;
  33. }

  34. static bool compare(char map1[MAX_MAP_SIZE][MAX_MAP_SIZE], char map2[MAX_MAP_SIZE][MAX_MAP_SIZE]) {
  35.    for (int y = 0; y < N; ++y)
  36.    for (int x = 0; x < N; ++x)
  37.       if (map1[y][x] != map2[y][x])
  38.          return false;

  39.    return true;
  40. }

  41. int main() {
  42.    int TC, totalscore, totalscan;
  43.    int t;//---
  44.    freopen("20180310i.txt", "r", stdin);

  45.    setbuf(stdout, NULL);
  46.    scanf("%d", &TC);
  47.    t=GetTickCount();
  48.    totalscore = totalscan = 0;
  49.    for (int testcase = 1; testcase <= TC; ++testcase) {
  50.       char guess[MAX_MAP_SIZE][MAX_MAP_SIZE];
  51.       int min_scan_count;

  52.       scanf("%d %d %d", &N, &seed, &min_scan_count);

  53.       makemap();

  54.       scancount = 0;

  55.       for (int y = 0; y < N; ++y)
  56.       for (int x = 0; x < N; ++x)
  57.          guess[y][x] = 0;

  58.       for (int k = 0; k < N; ++k) {
  59.          guess[k][0] = map[k][0];//第0列
  60.          guess[0][k] = map[0][k];//第0行
  61.          guess[k][1] = map[k][1];//
  62.          guess[1][k] = map[1][k];//
  63.          guess[k][N - 1] = map[k][N - 1];//
  64.          guess[N - 1][k] = map[N - 1][k];//
  65.          guess[k][N - 2] = map[k][N - 2];//第N-2列
  66.          guess[N - 2][k] = map[N - 2][k];//第N-2行
  67.       }

  68.       reconstruct(N, guess);

  69.       if (!compare(map, guess))
  70.          scancount = MAX_SCAN_COUNT;
  71.       totalscan += scancount;

  72.       int score;
  73.       if (TC == 5) { // sample testcase
  74.          score = scancount < MAX_SCAN_COUNT ? 100 : 0;
  75.          totalscore += score;
  76.       } else { // eval testcase
  77.          score = scancount <= min_scan_count + (min_scan_count / 2) ? 100 : 0;
  78.          totalscore += score;
  79.       }

  80.       printf("#%d %d\n", testcase, score);
  81.    }
  82.    t = GetTickCount() - t;
  83.    if (totalscan > MAX_SCAN_COUNT) totalscan = MAX_SCAN_COUNT;
  84.    printf("total score = %d, total scan = %d\n", totalscore / TC, totalscan);
  85.    printf("used time is %d\n", t);
  86.    return 0;
  87. }
  88. /*
  89. 5
  90. 8 26585 3
  91. 12 24059 28
  92. 16 26751 50
  93. 20 19164 100
  94. 24 10446 153
  95. */








阅读(1496) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

zhln2018-03-28 09:57:50

#1 100
#2 100
#3 100
#4 100
#5 100
total score = 100, total scan = 334
used time is 0