zoukankan      html  css  js  c++  java
  • E. Kuroni and the Score Distribution(思维 + 找规律)

    题目:传送门

    题意:让你构造一个长度为 n 的序列,使得 1 < a1 < a2 < ...... < an <= 1e9,且满足 1 < i < j < k <= n && a[ i ] + a[ j ] = a[ k ] 这样的三元组恰好只有 m 个,如果不能构造输出 -1.

    思路:

    首先,让所有 a[ i ] = i,这样的话,三元组共有 (i - 1) /  2  (i 从 1 到 n) 累加起来 个,且这个是最多的个数。那如果 m 大于累加得到的答案, 那么就不可能构造得出。(比赛的时候发现了这个规律)。

    这样的话,如果 m 恰巧等于某一段前缀和,那答案就很显然了,现在需要解决的是 m 不等于某一段前缀和的情况。这里需要发现另一个规律。

    你前 j 个都让 a[ j ] = j,然后你 a[ i ] 如果等于 i,那么会增加 (i - 1) / 2 组三元组,然后你会发现,你 a[ i ] = i + 2,你会增加 ( i - 3 ) / 2 组三元组,也就是说,你 i 每增加 2,你增加的三元组个数就减少 1,那就好办了,直接枚举某一段前缀和,然后构造出来,后面的就填那些不可能和前面的构成三元组的数就行了。

    #include <bits/stdc++.h>
    #define LL long long
    #define mem(i, j) memset(i, j, sizeof(i))
    #define rep(i, j, k) for(int i = j; i <= k; i++)
    #define dep(i, j, k) for(int i = k; i >= j; i--)
    #define pb push_back
    #define make make_pair
    #define INF INT_MAX
    #define inf LLONG_MAX
    #define PI acos(-1)
    using namespace std;
    
    const int N = 1e6 + 5;
    
    int a[N];
    
    void solve() {
    
        int n, m;
        scanf("%d %d", &n, &m);
    
        int res = 0;
        rep(i, 1, n) {
            res += (i - 1) / 2;
            if(res >= m) {
                rep(j, 1, i - 1) printf("%d ", j);
                printf("%d ", i + (res - m) * 2);
                int now = 500000000;
                rep(j, i + 1, n) printf("%d ",  now), now += 5000;
                return ;
            }
        }
        puts("-1"); return ;
    }
    
    int main() {
    
    //    int _; scanf("%d", &_);
    //
    //    while(_--) solve();
    
        solve();
    
        return 0;
    
    }
    一步一步,永不停息
  • 相关阅读:
    【转】当你输入一个网址的时候,实际会发生什么?
    opencv 操作本地摄像头实现录像
    谷歌笔试题——排序,只允许0和其他元素交换
    判断素数的相关代码
    VS2010 代码自动对齐 快捷键
    谷歌的一道面试题
    各种排序算法代码汇总
    冒泡排序
    lua环境变量
    lua迭代
  • 原文地址:https://www.cnblogs.com/Willems/p/12410554.html
Copyright © 2011-2022 走看看