zoukankan      html  css  js  c++  java
  • [构造]D. N Problems During K Days

    Polycarp has to solve exactly nn problems to improve his programming skill before an important programming competition. But this competition will be held very soon, most precisely, it will start in kk days. It means that Polycarp has exactly kk days for training!

    Polycarp doesn't want to procrastinate, so he wants to solve at least one problem during each of kk days. He also doesn't want to overwork, so if he solves xx problems during some day, he should solve no more than 2x2x problems during the next day. And, at last, he wants to improve his skill, so if he solves xx problems during some day, he should solve at least x+1x+1 problem during the next day.

    More formally: let [a1,a2,…,ak][a1,a2,…,ak] be the array of numbers of problems solved by Polycarp. The ii-th element of this array is the number of problems Polycarp solves during the ii-th day of his training. Then the following conditions must be satisfied:

    • sum of all aiai for ii from 11 to kk should be nn;
    • aiai should be greater than zero for each ii from 11 to kk;
    • the condition ai<ai+1≤2aiai<ai+1≤2ai should be satisfied for each ii from 11 to k−1k−1.

    Your problem is to find any array aa of length kk satisfying the conditions above or say that it is impossible to do it.

    Input

    The first line of the input contains two integers nn and kk (1≤n≤109,1≤k≤1051≤n≤109,1≤k≤105) — the number of problems Polycarp wants to solve and the number of days Polycarp wants to train.

    Output

    If it is impossible to find any array aa of length kk satisfying Polycarp's rules of training, print "NO" in the first line.

    Otherwise print "YES" in the first line, then print kk integers a1,a2,…,aka1,a2,…,ak in the second line, where aiai should be the number of problems Polycarp should solve during the ii-th day. If there are multiple answers, you can print any.

     题意 n个数m个空 求得一序列满足  a[i - 1] * 2 >= a[i] > a[i - 1]

    解题思路, 先构造一个和最接近n的连续序列

    则这个连续序列和n的差必然会小于m

    然后从尾按题目要求贪心填即可, 填补了则无解

    代码:

    /*
        Zeolim - An AC a day keeps the bug away
    */
    
    //pragma GCC optimize(2)
    #include <cstdio>
    #include <iostream>
    #include <bitset>
    #include <cstdlib>
    #include <cmath>
    #include <cctype>
    #include <string>
    #include <cstring>
    #include <algorithm>
    #include <stack>
    #include <queue>
    #include <set>
    #include <sstream>
    #include <map>
    #include <ctime>
    #include <vector>
    #include <fstream>
    #include <list>
    #include <iomanip>
    #include <numeric>
    #include <ext/pb_ds/tree_policy.hpp>
    #include <ext/pb_ds/assoc_container.hpp>
    using namespace std;
    //using namespace __gnu_pbds;
    //typedef tree <long long, null_type, less <long long>, rb_tree_tag, tree_order_statistics_node_update> rbtree;
    typedef long long ll;
    typedef long double ld;
    typedef unsigned long long ull;
    const ld PI = acos(-1.0);
    const ld E = exp(1.0);
    const int INF = 0x3f3f3f3f;
    const int MAXN = 1e6 + 10;
    const ll MOD = 1e9 + 7;
    
    ll n, m, arr[MAXN];
    
    bool check(ll x)
    {
    	return ( (x + x + n - 1) * n / ll(2) <= m);
    }
    
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);     cout.tie(0);
        //freopen("D://test.in", "r", stdin);
        //freopen("D://test.out", "w", stdout);
        
    	cin >> m >> n;
    
    	int fst = 1, lst = m, mid, ans = 1;
    
    	if(!check(1))
    	{
    		cout << "NO
    ";
    		return 0;
    	}
    
    	while(fst <= lst)
    	{
    		mid = (fst + lst) / 2;
    		if(check(mid))
    			fst = mid + 1, ans = mid;
    		else
    			lst = mid - 1;
    	}
    	
    	while(check(ans + 1))
    		++ans;
    		
    	for(int i = 0; i < n; ++i)
    		arr[i] = i + ans, m -= arr[i]; 
    
    
    	for(int i = n - 1; i >= 0 && m; --i)
    	{
    		if(arr[i - 1] * 2 - arr[i] >= m)
    		{
    			arr[i] += m, m = 0;
    			break;
    		}
    			
    		else
    		{
    			m -= (arr[i - 1] * 2 - arr[i]);
    			arr[i] = arr[i - 1] * 2;
    		}
    	}
    		
    	
    	if(m)
    	{
    		cout << "NO
    ";
    	}
    	else
    	{
    		cout << "YES
    ";
    		for(int i = 0; i < n; ++i)
    			cout << arr[i] << ' ';
    	}
    	
    		
        return 0;
    }
  • 相关阅读:
    时间处理得到UTC时间
    java数据同步陷阱
    360公司2016笔试题
    YTU 1439: 2.4.5 Fractions to Decimals 分数化小数
    YTU 2422: C语言习题 n个数逆序
    YTU 2421: C语言习题 矩形法求定积分
    YTU 2427: C语言习题 整数排序
    YTU 2832: 使用指针访问数组元素--程序填空
    YTU 1050: 写一个函数,使给定的一个二维数组(3×3)转置,即行列互换
    HDU 1069:Monkey and Banana
  • 原文地址:https://www.cnblogs.com/zeolim/p/12270369.html
Copyright © 2011-2022 走看看