鱼C论坛

 找回密码
 立即注册
12
返回列表 发新帖
楼主: zhangjinxuan

蒟蒻求助,这道题只得了44分,能帮忙看一下是哪里出了问题吗?

[复制链接]
发表于 2023-2-5 22:27:55 | 显示全部楼层
本帖最后由 jhq999 于 2023-2-5 22:29 编辑

提供一个思路:楼主试过从出口找入口?(注意行走都是反的,向上向左)
无标题.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-2-6 07:08:19 From FishC Mobile | 显示全部楼层
jhq999 发表于 2023-2-5 22:27
提供一个思路:楼主试过从出口找入口?(注意行走都是反的,向上向左)

感觉更麻烦了,效率反而会更慢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-2-6 14:16:21 | 显示全部楼层
我的思路是把每个小迷宫作为有向图里的一个节点,给终点创建一个虚拟的小迷宫(用第 n+1 个节点表示),小迷宫中从左上角到传送门(或终点)的距离作为对应的有向边的边长
先在每个小迷宫上跑 bfs 建图,然后在得到的图上跑 Floyd 最短路(写起来简单)找到终点的最少步数
然而评测记录里根本没有提交通过这道题(难道不登录看不到通过的提交?),而大样例我得到的结果和您的一样(我手工走了一遍,这个结果似乎是正确的?)
  1. #include <stdio.h>
  2. #include <stdint.h>
  3. #include <stdbool.h>
  4. #include <string.h>
  5. #include <stdlib.h>
  6. #include <ctype.h>
  7. static inline size_t min(size_t lhs, size_t rhs){ return lhs < rhs ? lhs : rhs; }
  8. struct location{
  9.     size_t x;
  10.     size_t y;
  11. };
  12. struct state{
  13.     struct location location;
  14.     size_t step_count;
  15. };
  16. struct state_node{
  17.     struct state state;
  18.     struct state_node* next;
  19. };
  20. struct state_queue{
  21.     struct state_node* head;
  22.     struct state_node* tail;
  23. };
  24. struct possible_location{
  25.     struct location location;
  26.     bool available;
  27. };
  28. void state_queue_init(struct state_queue* queue){
  29.     queue->head = queue->tail = NULL;
  30. }
  31. bool state_queue_empty(const struct state_queue* queue){
  32.     return queue->head == NULL;
  33. }
  34. void state_queue_push(struct state_queue* queue, struct state_node* node){
  35.     if(queue->head == NULL) queue->head = node;
  36.     else queue->tail->next = node;
  37.     node->next = NULL;
  38.     queue->tail = node;
  39. }
  40. struct state_node* state_queue_pop(struct state_queue* queue){
  41.     struct state_node* result = queue->head;
  42.     queue->head = result->next;
  43.     return result;
  44. }
  45. void state_queue_clear(struct state_queue* queue){
  46.     while(!state_queue_empty(queue)){
  47.         struct state_node* node = state_queue_pop(queue);
  48.         free(node);
  49.     }
  50. }
  51. bool check_destination(const struct location* location, const char* map, bool* visited, const size_t m){
  52.     if(location->x >= m || location->y >= m) return false;
  53.     if(visited[location->x * m + location->y]) return false;
  54.     char tile = map[location->x * m + location->y];
  55.     if(tile == '*') return false;
  56.     return true;
  57. }
  58. struct state_node* state_node_copy(const struct state_node* source){
  59.     struct state_node* node = malloc(sizeof(struct state_node));
  60.     node->next = NULL;
  61.     node->state.location = source->state.location;
  62.     node->state.step_count = source->state.step_count;
  63.     return node;
  64. }
  65. void walk_maze(
  66.     size_t* graph, const char* map, const bool* accessible,
  67.     const size_t n, const size_t m, bool* visited, struct state_queue* queue
  68. ){
  69.     memset(visited, 0, sizeof(bool) * m * m);
  70.     struct state_node* node = malloc(sizeof(struct state_node));
  71.     node->next = NULL;
  72.     node->state.location.x = 0;
  73.     node->state.location.y = 0;
  74.     node->state.step_count = 0;
  75.     visited[0] = true;
  76.     state_queue_push(queue, node);
  77.     while(!state_queue_empty(queue)){
  78.         node = state_queue_pop(queue);
  79.         char tile = map[node->state.location.x * m + node->state.location.y];
  80.         if(tile == '@' || isdigit(tile)){
  81.             if(isdigit(tile)){
  82.                 if(accessible[tile - '1']) graph[tile - '1'] = min(node->state.step_count, graph[tile - '1']);
  83.             }else{
  84.                 graph[n] = min(node->state.step_count, graph[n]);
  85.             }
  86.             free(node);
  87.             continue;
  88.         }
  89.         node->state.step_count += 1;
  90.         node->state.location.x += 1;
  91.         if(check_destination(&node->state.location, map, visited, m)){
  92.             state_queue_push(queue, state_node_copy(node));
  93.             visited[node->state.location.x * m + node->state.location.y] = true;
  94.         }
  95.         node->state.location.x -= 1;
  96.         node->state.location.y += 1;
  97.         if(check_destination(&node->state.location, map, visited, m)){
  98.             state_queue_push(queue, node);
  99.             visited[node->state.location.x * m + node->state.location.y] = true;
  100.         }else{
  101.             free(node);
  102.         }
  103.     }
  104. }
  105. void walk(size_t* graph, const char* map, const size_t n, const size_t m){
  106.     struct state_queue queue;
  107.     state_queue_init(&queue);
  108.     bool* visited = malloc(sizeof(bool) * m * m);
  109.     bool* accessible = malloc(sizeof(bool) * n);
  110.     for(size_t i = 0, offset = 0; i < n; i++, offset += m * m){
  111.         accessible[i] = map[offset] != '*';
  112.     }
  113.     for(size_t i = 0; i < n; i++){
  114.         walk_maze(graph + i * (n + 1), map + i * m * m, accessible, n, m, visited, &queue);
  115.     }
  116.     free(visited);
  117.     free(accessible);
  118. }
  119. void print_graph(const size_t* graph, const size_t n, FILE* stream){
  120.     for(size_t i = 0, offset = 0; i <= n; i++){
  121.         for(size_t j = 0; j <= n; j++, offset++){
  122.             if(graph[offset] == (size_t)-1) fprintf(stream, "%4d ", -1);
  123.             else fprintf(stream, "%4zu ", graph[offset]);
  124.         }
  125.         fputc('\n', stream);
  126.     }
  127. }
  128. int main(){
  129.     size_t n, m;
  130.     scanf("%zu%zu", &n, &m);
  131.     char* map = malloc(n * m * m);
  132.     for(size_t i = 0, offset = 0; i < n; i++){
  133.         for(size_t j = 0; j < m; j++, offset += m){
  134.             char c;
  135.             do{
  136.                 c = getchar();
  137.             }while(!isdigit(c) && c != '.' && c != '@' && c != '*');
  138.             ungetc(c, stdin);
  139.             fread(map + offset, m, 1, stdin);
  140.         }
  141.     }
  142.     size_t* graph = malloc(sizeof(size_t) * (n + 1) * (n + 1));
  143.     memset(graph, -1, sizeof(size_t) * (n + 1) * (n + 1));
  144.     walk(graph, map, n, m);
  145.     //print_graph(graph, n, stderr);
  146.     for(size_t k = 0; k <= n; k++) for(size_t i = 0; i <= n; i++) for(size_t j = 0; j <= n; j++){
  147.         if(graph[i * (n + 1) + k] == (size_t) -1 || graph[k * (n + 1) + j] == (size_t)-1) continue;
  148.         graph[i * (n + 1) + j] = min(graph[i * (n + 1) + k] + graph[k * (n + 1) + j], graph[i * (n + 1) + j]);
  149.     }
  150.     if(graph[n] == (size_t)-1) printf("-1\n");
  151.     else printf("%zu\n", graph[n]);
  152.     return 0;
  153. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-2-6 18:58:14 | 显示全部楼层
dolly_yos2 发表于 2023-2-6 14:16
我的思路是把每个小迷宫作为有向图里的一个节点,给终点创建一个虚拟的小迷宫(用第 n+1 个节点表示),小 ...

还是44
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-2-6 18:59:46 From FishC Mobile | 显示全部楼层
zhangjinxuan 发表于 2023-2-6 18:58
还是44

《符合预期》
毕竟大样例上和您的代码结果一致
严重怀疑题目有问题,至少输入格式是不符合题面描述的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-2-6 19:06:52 | 显示全部楼层
dolly_yos2 发表于 2023-2-6 18:59
《符合预期》
毕竟大样例上和您的代码结果一致
严重怀疑题目有问题,至少输入格式是不符合题面描述的

我还怀疑样例有问题,要不是样例太大,我当场就调出来
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-2-6 19:41:09 From FishC Mobile | 显示全部楼层
zhangjinxuan 发表于 2023-2-6 19:06
我还怀疑样例有问题,要不是样例太大,我当场就调出来

样例很可能有问题,如果题意没理解错的话得到的这个结果(71)是能走出来的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-2-6 20:24:41 | 显示全部楼层
dolly_yos2 发表于 2023-2-6 19:41
样例很可能有问题,如果题意没理解错的话得到的这个结果(71)是能走出来的

但我们不能手算出来,就没有证据去说
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-2-8 16:11:09 | 显示全部楼层
本帖最后由 jhq999 于 2023-2-8 17:07 编辑
zhangjinxuan 发表于 2023-2-6 20:24
但我们不能手算出来,就没有证据去说

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #define maxnum 0x7fffffff
  4. int m,n,end;
  5. char pt[9][1000][1000];
  6. typedef struct NODE
  7. {
  8.     int len,minpath;
  9.     int num[10][5];
  10. }node;
  11. node nums[10];
  12. int num[100],numend[100]={0},nmpt=0;
  13. int min=maxnum,flag=0;
  14. void pushnum(int a)
  15. {
  16.     num[nmpt++]=a;
  17. }
  18. int popnum()
  19. {
  20.     return num[--nmpt];
  21. }
  22. int exitpoint(char (*p)[m][m],int i,int j,int k)
  23. {
  24.     //char c1=p[i][j-1][k],c2=p[i][j][k-1];
  25.     char a=p[i][j-1][0],b=p[i][0][k-1];
  26.     if((j&&k&&(p[i][j-1][k]||p[i][j][k-1]))||(j&&0==k&&p[i][j-1][0])||(0==j&&k&&p[i][0][k-1])||(0==j&&0==k))
  27.     {
  28.         end=i+1;
  29.         nums[i+1].len=maxnum;
  30.         nums[i+1].num[0][1]=j+k;
  31.         return 0;
  32.     }
  33.     return -1;
  34. }
  35. void numpoint(char (*p)[m][m],int i,int j,int k)
  36. {
  37.     if(0==p[p[i][j][k]-'1'][0][0])
  38.     {
  39.         p[i][j][k]=1;
  40.     }
  41.     else
  42.     {
  43.         char c=p[i][j][k];
  44.         if((i!=p[i][j][k]-'1')&&((j&&k&&(p[i][j-1][k]||p[i][j][k-1]))\
  45.                                  ||(j&&0==k&&p[i][j-1][0])||(0==j&&k&&p[i][0][k-1])||(0==j&&0==k)))
  46.         {
  47.             nums[i+1].len=maxnum;
  48.             nums[i+1].num[p[i][j][k]-'0'][0]=1;
  49.             if(j+k<nums[i+1].num[p[i][j][k]-'0'][1])
  50.             {
  51.                 nums[i+1].num[p[i][j][k]-'0'][1]=j+k;
  52.                 nums[i+1].num[p[i][j][k]-'0'][2]=i,nums[i+1].num[p[i][j][k]-'0'][3]=j,nums[i+1].num[p[i][j][k]-'0'][4]=k;
  53.             }
  54.         }
  55.         if(j||k)p[i][j][k]=0;
  56.         else
  57.         {
  58.             p[i][j][k]='n';
  59.         }

  60.     }
  61. }
  62. void point(char (*p)[m][m],int i,int j,int k)
  63. {
  64.     if(j)
  65.     {
  66.         if(k)
  67.         {
  68.             p[i][j][k]=p[i][j-1][k]||p[i][j][k-1];

  69.         }
  70.         else
  71.             p[i][j][k]=p[i][j-1][k];

  72.     }
  73.     else if(k)
  74.     {
  75.         p[i][j][k]=p[i][j][k-1];
  76.     }
  77. }
  78. int inidata(char (*p)[m][m])
  79. {
  80.     int i,j,k;
  81.     for(i=0; i<n; i+=1)
  82.     {
  83.         for(j=0; j<m; j+=1)
  84.         {
  85.             for(k=0; k<m; k+=1)
  86.             {
  87.                 if('.'==p[i][j][k])
  88.                     point(p,i,j,k);
  89.                 else if('0'<=p[i][j][k]&&'9'>=p[i][j][k])
  90.                 {
  91.                     numpoint(p,i,j,k);
  92.                     if(0==(j||k))j=m,k=m;
  93.                 }
  94.                 else if('@'==p[i][j][k])
  95.                 {

  96.                     if(-1==exitpoint(p,i,j,k))return -1;
  97.                     j=m,k=m;
  98.                 }

  99.             }
  100.         }
  101.     }

  102.     return 0;
  103. }
  104. int findminpath()
  105. {
  106.     int id;
  107.     pushnum(1);
  108.     nums[1].len=0;//////重要,起点赋值为0
  109.     while(nmpt)
  110.     {
  111.         id=popnum();

  112.         for(int i=1; i<10; i+=1)
  113.         {
  114.             if(nums[id].num[i][0])
  115.             {
  116.                 pushnum(i);
  117.                 nums[i].num[id][0]=0;
  118.                 nums[id].num[i][0]=0;
  119.                 if(nums[i].len>nums[id].num[i][1]+nums[id].len)
  120.                 {
  121.                     nums[i].len=nums[id].num[i][1]+nums[id].len;
  122.                     nums[i].minpath=id;
  123.                 }


  124.             }
  125.         }




  126.     }
  127.     return 0;
  128. }
  129. int main()
  130. {


  131.     int i,j,k;
  132.     for(i=0;i<10;i+=1)
  133.         for(j=0;j<10;j+=1)
  134.             nums[i].num[j][1]=maxnum;
  135.     char t;
  136.     FILE *fp=fopen("1.in","rb");
  137.     fseek(fp,0,SEEK_END);
  138.     int len=ftell(fp),len1=6;
  139.     fseek(fp,0,SEEK_SET);
  140.     fscanf(fp,"%d%d",&n,&m);
  141.     for(i=0; i<n; i+=1)
  142.     {
  143.         for(j=0; j<m; j+=1)
  144.         {
  145.             for(k=0; k<m;)
  146.             {
  147.                 len1+=1;
  148.                 fread(&t,1,1,fp);
  149.                 if('.'==t)
  150.                 {
  151.                     pt[i][j][k++]=1;
  152.                 }
  153.                 else if('*'==t)
  154.                 {
  155.                     pt[i][j][k++]=0;
  156.                 }
  157.                 else if(('0'<=t&&'9'>=t)||('@'==t))
  158.                 {
  159.                     pt[i][j][k++]=t;
  160.                 }

  161.             }
  162.         }
  163.     }
  164.     if(-1==inidata(pt))
  165.     {
  166.         printf("-1\n");
  167.     }
  168.     else
  169.     {
  170.         findminpath();
  171.         if(maxnum==nums[end].len)printf("-1");
  172.         else
  173.             printf("%d\n",nums[end].len+nums[end].num[0][1]);
  174.     }
  175.     i=end;
  176.     while(i>1)
  177.     {
  178.         int t=i;
  179.         i=nums[i].minpath;
  180.         printf("%d %d %d %d %d\n",i,nums[i].len,nums[i].num[t][2]+1,nums[i].num[t][3],nums[i].num[t][3]);
  181.     }
  182.     ////////////////////////////////////
  183.     fclose(fp);
  184.     return 0;
  185. }
复制代码
  1. 71///////@在9层的(0,0)
  2. ////////第一个数是层数,第二个数是此层到下层的最短路径,剩下的是层数,行,列
  3. 6 25 6 20 5////////6层(0,0)到数字9的最短的那个9的长度,坐标(20,5)
  4. 8 14 8 11 3///////8层(0,0)到数字6的最短的那个6的长度,坐标(8,11)
  5. 1 32 1 28 4///////1层(0,0)到数字8的最短的那个8的长度,坐标(28,4)
复制代码

无标题.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-2-8 18:16:23 | 显示全部楼层


RE(运行时错误),非常奇妙,会不会是环境问题
而且我用C++会CE(编译错误)
不过,你找到证据啦
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-2-8 19:13:55 | 显示全部楼层
本帖最后由 jhq999 于 2023-2-8 19:15 编辑
zhangjinxuan 发表于 2023-2-8 18:16
RE(运行时错误),非常奇妙,会不会是环境问题
而且我用C++会CE(编译错误)
...


我提交了只有10分,,谁知道什么毛病,我用的是图的最短路径,每个层的左上角为点,能够联通的两个层为边,路径为权值。
每个层左上角到这个层每个数字的最短路径是唯一的,不是最短的变成石头‘*’
每个左上角到能够到达的数字的路径长就是数字坐标的行和列的和
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-2-8 19:16:41 | 显示全部楼层
jhq999 发表于 2023-2-8 19:13
我提交了只有10分,,谁知道什么毛病,我用的是图的最短路径,每个层的左上角为点,能够联通的 ...

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-2-8 19:27:17 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-5-11 13:57

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表