• UVa 10142 Australian Voting


    题目链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=29&page=show_problem&problem=1083

    题意:这个题刘汝佳在挑战编程上翻译的让我各种费解,后来看了这个翻译才明白:http://hi.baidu.com/knowledgetime/blog/item/6017ea04bb35cfc37a894779.html

    摘抄如下:

    UVa 10142 - Australian Voting 
    澳大利亚在选举的时候,他们要求投票者在选票上将候选人做一个排名的动作。一开始先计算所有选票中的「第一选择」,如果有某位候选人在此时获得过半(50%)的选票,那么这位候选人立即当选。如果没有任何候选人获得过半的选票,那么票数最少的所有候选人将被排除当选资格,那些原本选择这些候选人的选票,则依照顺位将票投给下一个仍未出局的候选人。这个流程不断的重复(每一次的计票,票数最少的那些候选人都被排除当选),

    或者是所有剩下的候选人得票数相同才停止 

    Input 

    输入的第一列和第一笔测试资料之间,以及连续两笔测试资料之间都包含了一列空白。 

    输入的第一列有一个整数n (n<=20)代表候选人的个数。接下来的n列每一列依序表示了候选人的名字。这些名字可能长达80个可印出的字元。 

    然后会有至多1000列,每一列包含了一张选票的内容。每一张选票都包含了一个1~n的排列,第一个数代表这张选票上的「第一选择」,第二个数字代表第二顺位…以此类推。 

    Output 

    对于任两笔连续的测试资料中间请输出一列空白。 

    对每一组测试资料输出赢得选举的候选人名字,或是同时打成平手的所有候选人名字。
     

    Sample Input 



    John Doe 
    Jane Smith 
    Sirhan Sirhan 
    1 2 3 
    2 1 3 
    2 3 1 
    1 2 3 
    3 1 2 


    Sample Output 
    John Doe 

    这个题只要明确了题意剩下的就比较简单了。

      1 #include <cstdio>
      2 #include <cstring>
      3 
      4 const int MAXN = 1010;
      5 
      6 struct vote      //每张选票
      7 {
      8     int who[25];
      9 };
     10 
     11 vote V[MAXN];           //每张选票
     12 char name[25][100];     //候选人名单
     13 bool vis[25];           //记录该候选人是否出局
     14 int count[25];          //每个候选人的票数
     15 int n, k;
     16 
     17 void Solve()
     18 {
     19     memset( vis, true, sizeof(vis) );
     20     int left = 0;
     21 
     22     bool flag = true;             //是否继续统计票数
     23     bool getans = false;          //是否平局
     24 
     25     while ( flag )
     26     {
     27         memset( count, 0, sizeof(count) );
     28         for ( int i = 0; i < k; i++ )
     29         {
     30             for ( int j = 0; j < n; j++ )
     31             {
     32                 int& peo = V[i].who[j];
     33                 if ( vis[ peo - 1 ] )
     34                 {
     35                     ++count[ peo - 1 ];
     36                     break;
     37                 }
     38             }
     39         }
     40 
     41         //   for ( int i = 0; i < n; i++ ) printf( "%d ", count[i] );
     42         //         putchar('\n');
     43 
     44         for ( int i = 0; i < n; i++ )
     45         {
     46             if ( count[i] > k / 2 )          //如果有人票数过半
     47             {
     48                 puts( name[i] );
     49                 flag = false;
     50                 getans = true;
     51                 break;
     52             }
     53         }
     54         if ( !flag ) break;                  //如果有人票数过半,则输出结果,统计结束
     55 
     56         flag = false;
     57         int old;
     58         int i;
     59         left = 0;
     60         for ( i = 0; i < n; i++ )
     61             if ( vis[i] )
     62             {
     63                 old = count[i];
     64                 ++left;
     65                 break;
     66             }
     67         for ( ++i; i < n; i++ )              //判断是否剩下的人票数相同
     68             if ( vis[i] )
     69             {
     70                 ++left;
     71                 if ( count[i] != old )
     72                 {
     73                     flag = true;
     74                     break;
     75                 }
     76             }
     77         if ( !flag || left == 1 ) break;     //如果平局,或者只剩一个候选人,输出结果,退出
     78 
     79         int min = 2000;
     80         for ( int i = 0; i < n; i++ )
     81             if ( vis[i] )                  //少了这个vis,TLE了三遍,进死循环了
     82                 if ( count[i] < min ) min = count[i];
     83 
     84         for ( int i = 0; i < n; i++ )      //每次票数最少的人出局
     85             if ( vis[i] )
     86                 if ( count[i] == min )  vis[i] = false;
     87     }
     88 
     89     if ( !getans )                         //如果平局,输出所有并列的候选人
     90     {
     91         for ( int i = 0; i < n; i++ )
     92             if ( vis[i] ) puts( name[i] );
     93     }
     94 
     95     return;
     96 }
     97 
     98 int main()
     99 {
    100     //  freopen( "s.txt", "w", stdout );
    101     int T;
    102     char str[100];
    103     scanf( "%d", &T );
    104     while ( T-- )
    105     {
    106         scanf( "%d", &n );
    107         getchar();
    108         for ( int i = 0; i < n; i++ )                    //读入候选人名单
    109             gets( name[i] );
    110 
    111         k = 0;
    112         while ( gets( str ) != NULL && str[0] != '\0' )  //读入选票
    113         {
    114             int len = strlen(str);
    115             int j = 0;
    116             for ( int i = 0; i < len; i++ )
    117             {
    118                 if ( str[i] != ' ' )
    119                 {
    120                     int cnt = 0;
    121                     while ( str[i] != ' ' && str[i] != '\0' )
    122                         cnt = cnt * 10 + ( str[i++] - '0' );
    123                     V[k].who[j++] = cnt;
    124                 }
    125             }
    126             ++k;
    127         }
    128 
    129         Solve();
    130 
    131         if (T) putchar('\n');
    132     }
    133     return 0;
    134 }
  • 相关阅读:
    【STM32H7的DSP教程】第28章 FFT和IFFT的Matlab实现(幅频响应和相频响应)
    【STM32F429的DSP教程】第28章 FFT和IFFT的Matlab实现(幅频响应和相频响应)
    【STM32F407的DSP教程】第28章 FFT和IFFT的Matlab实现(幅频响应和相频响应)
    《安富莱嵌入式周报》第209期:2021.04.19--2021.04.25
    H7-TOOL的APP固件升级至V2.04,上位机升级至V2.04,新增南京沁恒CH32,华大HC32和中科芯CKS32脱机烧录支持(2021-04-24)
    【STM32H7】第9章 ThreadX任务管理
    【STM32F429】第9章 ThreadX任务管理
    【STM32H7】第8章 ThreadX调试方法(串口和RTT两种方式打印任务执行情况)
    【STM32F429】第8章 ThreadX调试方法(串口和RTT两种方式打印任务执行情况)
    《安富莱嵌入式周报》第208期:2021.04.12--2021.04.18
  • 原文地址:https://www.cnblogs.com/GBRgbr/p/2649596.html
Copyright © 2020-2023  润新知