• POJ 2356 && POJ 3370 鸽巢原理


    POJ 2356:

    题目大意:

    给定n个数,希望在这n个数中找到一些数的和是n的倍数,输出任意一种数的序列,找不到则输出0

    这里首先要确定这道题的解是必然存在的

    利用一个 sum[i]保存前 i 个数的和对n的取模

    sum[0] = 0;

    那么sum[0] ~ sum[n]有n+1个数据,这些数据的范围都是 0~n , 要是存在 sum[i] = 0,那么输出前 i 个数据即可

    要是不存在那根据鸽巢原理可以说明必然能找到一个 sum[i] = sum[j]  ,那么说明 (sum[i+1] + sum[i+2] ...+sum[j])%n = 0的,把这j-i个数输出即可

    那么说明我们总是能找到一段连续的数据使其和是n的倍数

     1 #include <cstdio>
     2 #include <cstring>
     3 
     4 using namespace std;
     5 const int N = 10005;
     6 
     7 bool vis[N];
     8 int sum[N] , a[N] , pos[N];
     9 
    10 int main()
    11 {
    12    // freopen("a.in" , "r" , stdin);
    13     int n;
    14     while(scanf("%d" , &n) != EOF)
    15     {
    16         for(int i=1 ; i<=n ; i++){
    17             scanf("%d" , a+i);
    18         }
    19         memset(vis , 0 , sizeof(vis));
    20         vis[0] = 1 , pos[0] = 0;
    21         for(int i=1 ; i<=n ; i++){
    22             sum[i] = (sum[i-1]+a[i])%n;
    23             if(vis[sum[i]]){
    24                 int l = pos[sum[i]];
    25                 printf("%d
    " , i-l);
    26                 for(int j = l+1 ; j<=i ; j++){
    27                     printf("%d
    " , a[j]);
    28                 }
    29                 break;
    30             }
    31             pos[sum[i]] = i;
    32             vis[sum[i]] = 1;
    33         }
    34     }
    35     return 0;
    36 }

    POJ3370:

     1 #include <cstdio>
     2 #include <cstring>
     3 
     4 using namespace std;
     5 #define N 100005
     6 bool vis[N];
     7 int sum[N] , a[N] , pos[N];
     8 
     9 int main()
    10 {
    11    // freopen("a.in" , "r" , stdin);
    12     int c , n;
    13     while(scanf("%d%d" , &c , &n) , c||n)
    14     {
    15         for(int i=1 ; i<=n ; i++)
    16             scanf("%d" , a+i);
    17         memset(vis , 0 ,sizeof(vis));
    18         sum[0] = 0 , vis[0] = 1 , pos[0] = 0;
    19         for(int i=1 ; i<=n ; i++){
    20             sum[i] = (sum[i-1] + a[i])%c;
    21             if(vis[sum[i]]){
    22                 int l = pos[sum[i]];
    23                 for(int j=l+1 ; j<=i ; j++){
    24                     if(j == l+1) printf("%d" , j);
    25                     else printf(" %d" , j);
    26                 }
    27                 printf("
    ");
    28                 break;
    29             }
    30             vis[sum[i]] = 1;
    31             pos[sum[i]] = i;
    32         }
    33     }
    34     return 0;
    35 }
  • 相关阅读:
    SGU 107
    HDU 1724 自适应辛普森法
    POJ 1061 扩展欧几里得
    zzuli2424: 越靠近,越幸运(dfs)
    zzuli1519: 小P参加相亲大会(异或)
    zzuli1519: 小P参加相亲大会(异或)
    牛客练习赛42 A:字符串
    牛客练习赛42 A:字符串
    zzuli1511: 小P的loI
    zzuli1511: 小P的loI
  • 原文地址:https://www.cnblogs.com/CSU3901130321/p/4244214.html
Copyright © 2020-2023  润新知