zoukankan      html  css  js  c++  java
  • hihocoder 1246 王胖浩与环

    题意:

    给出一个环,环上有n(<=2000)个数字(<=5e7),然后将这个环分成1~n个连续序列,各个序列和之间的最大公因数。

    题解:

    我一开始想到的是二分,然后对于二分就会想怎么check,那么可以枚举这n个数和的因数,因为答案一定在这里面,然后就会找出对于每个因数可以分成的段数,但是这个并不满足单调性QAQ,但提供了一定的思路

    考虑从大到小枚举因数,然后对于这个因数分成尽量多的部分,因为不难知道如果a % x == 0,(a + b) % x == 0 那么b % x == 0,因为这样就可以一直贪心找最大的因数。

    然后现在的问题就是考虑环的情况,一般的做法是断环为链,枚举起点到终点找出有多少段%x == 0,但是可以稍微变一下形,如果pre[i] % x == y, pre[j] % x == y,那么i ~ j这一段%x为0,那么(1 ~ i) + (j+1 ~ n) % x == 0,那么现在的问题就是统计余数出现最多的次数,就完美处理了环的情况。

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N = 4e3 + 7;
    #define LL long long
    vector <LL> num;
    int n;
    LL pre[N];
    
    int main () {
    	scanf ("%d", &n);
    	for (int i = 1; i <= n; ++i) {
    		int x;
    		scanf ("%d", &x);
    		pre[i] = pre[i-1] + x;
    	}
    	for (LL i = 1; i * i <= pre[n]; ++i) {
    		if (pre[n] % i == 0) {
    			if (i * i == pre[n]) {
    				num.push_back(i);
    				continue;
    			}
    			num.push_back(i);
    			num.push_back(pre[n] / i);
    		}
    	}
    	sort (num.begin(), num.end());
    	int K = 1;
    	for (int i = num.size() - 1; i >= 0; --i) {
    		int maxi = 0;
    		vector <LL> v;
    		for (int j = 1; j <= n; ++j) v.push_back(pre[j] % num[i]);
    		sort (v.begin(), v.end());
    		int pre = 0;
    		for (int j = 0; j < v.size(); ++j) {
    			if (v[j] == v[j+1] && j != v.size()-1) continue;
    			maxi = max (maxi, j - pre + 1);
    			pre = j + 1;
    		}
    		while (K <= maxi) {
    			printf ("%lld
    ", num[i]);
    			++K;
    		}
    	}
    	return 0;
    }
    

      

    总结:

    这种求因数的题,并且数的范围不大,可以直接暴力枚举因数。。。。。。还有注意的是公式的变换~

  • 相关阅读:
    SpringMVC简单总结-day02
    SpringMVC简单总结-day01
    SpringMVC通过Ajax处理数据,出现406问题
    Java特殊时间格式转化
    PyQuery用法详解
    解决:CentOS 7下yum install mysql-server无包可用问题
    数据库编程接口
    python高级文件操作
    python生成随机数、随机字符串
    【转】错误日志ID8021来源BROWSER导致电脑死机
  • 原文地址:https://www.cnblogs.com/xgtao/p/6014657.html
Copyright © 2011-2022 走看看