zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    Windows快捷方式的形式关机方法
    [Andriod官方训练教程]创建你的第一个App之创建一个简单的用户界面
    使用GDAL对HDF数据进行geoloc校正
    破解sqlyog 30天试用限制
    [Andriod官方训练教程]创建你的第一个App之运行你的App
    [Andriod官方训练教程]创建你的第一个App之开始另一个Activity
    GDAL对空间数据的管理
    win linux 下 部署war包到Tomcat根目录
    Spring session
    使用GDAL对HDF数据进行校正
  • 原文地址:https://www.cnblogs.com/CSU3901130321/p/4244214.html
Copyright © 2011-2022 走看看