zoukankan      html  css  js  c++  java
  • 河南省第二届ACM程序设计大赛解题报告(置换群)

    1.

     1 /*
     2 前两道题一直在纠结提议,特别是第二题,看了别人的代码才明白过来题意,由测试用例都没明白 
     3 */
     4 #include <iostream>
     5 #include <cstring>
     6 #include <queue>
     7 using namespace std;
     8 
     9 const int maxn = 55;
    10 int ins[maxn];
    11 bool vis[maxn] = {false};
    12 int N,A,B;
    13 
    14 //假设边界在AB之间 
    15 int solve()
    16 {
    17     /*
    18     刚开始忘记了开标记数组,要保证每个节点只访问一次,否则会死循环 
    19     */
    20     int a = max(A,B);
    21     int b = min(A,B);
    22     queue <int > q;
    23     int cnt = 0;
    24     while(!q.empty())
    25         q.pop();
    26     q.push(A);
    27     vis[A] = true;
    28     bool flag = false;
    29     while(!q.empty())
    30     {
    31         cnt++;
    32         int head = q.front();
    33         q.pop();
    34         int left = head - ins[head];
    35         int right = head + ins[head];
    36         if(left>=b&&!vis[left])
    37         {
    38             if(left==B)
    39             {
    40                 flag = true;
    41                 break; 
    42             }
    43             vis[left] = true;
    44             q.push(left);
    45         }
    46         if(right<=a&&!vis[right])
    47         {
    48             if(right==B)
    49             {
    50                 flag = true;
    51                 break; 
    52             }
    53             vis[right] = true;
    54             q.push(right);
    55         }
    56     }
    57     if(flag)
    58         return cnt; 
    59     else
    60         return -1;     
    61 }
    62 
    63 int main()
    64 {
    65     int i,j,k;
    66     int M;
    67     
    68     cin>>M;
    69     while(M--)
    70     {
    71         memset(vis,false,sizeof(vis));
    72         memset(ins,0,sizeof(ins));
    73         
    74         cin>>N>>A>>B;
    75         for(i=1; i<=N; i++)
    76         {
    77             cin>>ins[i];
    78         }
    79         int ans = solve();
    80         cout<<ans<<endl;
    81     }
    82     return 0;
    83     
    84 }

    2.刚开始用list写的,太恶心了,写不成,就换成直接的链表了
      

     1 #include <iostream>
     2 #include <cstring>
     3 using namespace std;
     4 
     5 int N,K;
     6 typedef struct Node 
     7 {
     8     int data;
     9     Node * next;
    10 }Node;
    11 
    12 Node *head;
    13 void init()
    14 {
    15     //头结点也要申请空间 
    16     head = new Node;
    17     head->data = 0;
    18     head->next = NULL;
    19     //头插法 
    20     for(int i=1; i<=N; i++)
    21     {
    22         Node *p = new Node;
    23         p->next = head->next;
    24         head->next = p;
    25         p->data = N-i+1;
    26     }   
    27 }
    28 
    29 int main()
    30 {
    31     int i,j,k;
    32     cin>>N>>K;
    33     int a,b,c;
    34     init();
    35     for(i=1; i<=K; i++)
    36     {
    37         cin>>a>>b>>c;
    38         Node *p,*q,*r;
    39         Node *temp1, *temp2, *temp3;
    40         
    41         int cnt = 0;
    42         for(p=head; cnt<a-1; cnt++,p=p->next);
    43         temp1 = p;
    44         
    45         cnt = 0;
    46         for(p=head; cnt<b; cnt++,p=p->next);
    47         temp2 = p;
    48         
    49         cnt = 0;
    50         for(p=head; cnt<c; cnt++,p=p->next);
    51         temp3 = p;
    52         
    53         Node *temp4 = temp2->next;
    54         temp2->next = temp3->next;
    55         temp3->next = temp1->next;
    56         temp1->next = temp4;
    57     }
    58     Node *p;
    59     int cnt = 0;
    60     for(p=head->next,cnt=0; cnt<10; cnt++,p=p->next)
    61     {
    62         cout<<p->data<<endl;
    63         
    64     }
    65     while(1);
    66     return 0;
    67 }

    3.

    4.参考华杰做出来的  

     1 //置换群问题 
     2 /*
     3 求最小费用时求较小着:用分解后的每个循环里的最小值,或者全局最小值 
     4 */
     5 #include <iostream>
     6 #include <cstring>
     7 #include <cstdlib>
     8 #include <algorithm>
     9 using namespace std;
    10 
    11 const int maxn = 1010;
    12 int N;
    13 int g_min = 1010;//全局置换群最小值,题目上说最大高度是1000 ,每次的全局最小会改变,不能是const 
    14 
    15 int hash[maxn],a[maxn],b[maxn];
    16 bool vis[maxn];
    17 
    18 int solve()
    19 {
    20     memset(vis,false,sizeof(vis)); 
    21     int i,j,k;
    22     //若分解后的循环里面只有一个元素,则该元素在原来的群里面必定是排好序的
    23     int len = N;
    24     int l_min = 1010;//局部最小值 
    25     int ans = 0;
    26     while(len>0)
    27     {
    28         int i = 0;
    29         int length = 0;//循环的长度 
    30         //vis数组标记的是输入的顺序,先找到第一个后,那么经过下面的操作后第一个循环就被全部标记过了 
    31         while(vis[i])
    32         {
    33             i++;
    34         }
    35         int begin = i;
    36         int sum = 0;//每次循环的所有元素和 
    37         //找循环
    38         /*
    39         必须用 do while(至少执行一次),或者死循环里用break;不可while(i!=begin)这样的话 因为int begin = i则大循环一直执行 
    40         */
    41         do
    42         {
    43             length++;
    44             vis[i] = true;//i是个下标值 ,放在i改变之前                
    45             if(l_min>a[i])
    46                 l_min = a[i]; 
    47             sum += a[i];
    48             //hash数组返回的只是一个下标值 
    49             i = hash[b[i]];//返回的是起点对应的下标所对应元素的下标 ,必须放在sum之后 
    50         }while(begin!=i);
    51         
    52         len -= length;//必须在continue之前 
    53         if(length==1)//必须有 ,表示循环里只有一个元素,则不花费代价 
    54             continue;
    55                   
    56         //ans1用的是循环内最小值,sum存的是循环内所有的元素和 ,局部最小元素用了 (length-1)次,其他的用了一次,因为在sum
    57         //里已经加了一次局部最小,所以 length-2)*l_min;
    58         int ans1 = sum + (length-2)*l_min;
    59         //全局的先把局部的换出来最后还要在换回来 ,所以答案是两次全局 + 两次局部 + sum里除了局部之外的其他元素和 
    60         int ans2 = sum + l_min + (length+1)*g_min;
    61         
    62         ans += ans1>ans2?ans2:ans1;//是累计,不是直接赋值 
    63     }
    64     return ans;    
    65 }
    66 
    67 int main()
    68 {
    69     int i,j,k;
    70     int T;
    71     cin>>T;
    72     while(T--)
    73     {
    74         cin>>N;
    75         memset(hash,0,sizeof(hash));
    76         memset(a,0,sizeof(a));
    77         memset(b,0,sizeof(b));
    78       
    79         
    80         for(i=0; i<N; i++)
    81         {
    82             cin>>a[i];
    83             b[i] = a[i];//排好序的数组 
    84             if(g_min>a[i])
    85             {
    86                 g_min = a[i];
    87             }
    88             hash[a[i]] = i;
    89         }
    90         sort(b,b+N);
    91         int ans = solve();
    92         cout<<ans<<endl; 
    93     }
    94     system("pause");
    95     return 0;
    96 }
  • 相关阅读:
    linux Chrome 安装
    jQuery.extend 函数详解
    Ubuntu Linux 下文件名乱码(无效的编码)的快速解决办法
    Django——model字段类型 2
    Django 中的用户认证
    Expression<Func<T, bool>>与Func<T, bool>的区别
    根据funID,personID获取最新规划包项目相关信息
    SET ANSI_NULLS ON 在T-SQL中是什么意思
    SQL Server 2008中如何为XML字段建立索引
    PowerDesigner 建模后如何导入到数据库
  • 原文地址:https://www.cnblogs.com/hxsyl/p/3043678.html
Copyright © 2011-2022 走看看