2018年四川ICPC省赛J题  2813: JoJo’s Bizarre Adventure (思维 + STL)

5 篇文章 0 订阅
2 篇文章 0 订阅

 2813: JoJo’s Bizarre Adventure

Time Limit: 1000 MS Memory Limit: 1048576 KB
Total Submit: 60 Accepted: 12 Page View: 187
Submit Status Discuss

Description 

Dio and JoJo are playing a game.

At the beginning, JoJo writes down nn non-negative integers a1;a2;...;ana1;a2;...;an(0=a1≤a2≤⋅⋅⋅≤an0=a1≤a2≤···≤an) on a sheet of paper and a1=0a1=0 is guaranteed. Then, he makes a multiset Smulti={ai+aj|1≤i<j≤n}Smulti={ai+aj|1≤i<j≤n}, and tells the numbers to Dio within Smulti in non-decreasing order one after another.

As for Dio, he wins the game if and only if he can determine the original nn numbers aiai(1≤i≤n1≤i≤n) after receiving some of the numbers in Smulti given by JoJo.

If Dio can't win the game as soon as possible, he won't be a human anymore. So can you help him determine the earliest time to win?

Input 

The first line contains a integer TT representing the number of test cases. In each test case, the first line contains one integer nn. The second line contains n×(n−1)2n×(n−1)2 integers, the i−thi−th integer sisi represents the i−thi−th element in SmultiSmulti. It is guaranteed that the numbers in SmultiSmulti are generated by some nn non-negative integers a1;...;ana1;...;an and given in non-decreasing order. • 1≤T≤101≤T≤10 • 1≤n≤5001≤n≤500 • 0≤si≤1090≤si≤109 • 0<∑n≤10000<∑n≤1000

Output 

For each test case, output a number xx in one line indicating that after receiving xx sums, Dio can determine the original nn numbers.

2 4 1 2 3 3 4 5 4 1 2 2 3 3 4

4 3

Hint 

In the first test case, {0;1;2;3}{0;1;2;3} can be determined as the initial numbers after receiving 4 numbers. In the second test case, {0;1;2;2}{0;1;2;2} can be determined as the initial numbers after receiving 3 numbers.

Source 

The 2018 Sichuan Provincial Collegiate Programming Contest

Tags  

 

告诉你一个s的集合,以非递减顺序给出

问你得到s的前多少项,可以得到这个s的集合所有元素

a_i + a_j = s_k

 

可以考虑删数, 1 2 3 3 4 5 

刚开始我们有0,所以拿出来 1 ,可以得到 1 , 直接把1的第一个位置删除

现在就有 0 和 1,再拿出来 2 ,可以得到 2,3  然后又把第一个出现 2 ,3 的位置删除

然后现在又有0,1,2,3 , 再拿出来 3, 可以得到 3,4,5,6 删除第一次出现的会发现 只需要在第2个3的时候,就可以得到这个s集合里所有的数字了,所以ans = 4

 

因为全都是非递减给出的 , 那我们先把所有的数都入set,然后对于每个最小的set中的元素,每次二分一下最开始的位置就可以了。当set都空的时候,就可以找到答案了。


#include <bits/stdc++.h>
#include <time.h>
#define fi first
#define se second
#define endll "\n"
#define MS0(X) memset((X), 0, sizeof((X)))
#define MS1(X) memset((X), -1, sizeof((X)))
#define LEN(X) strlen(X)
#define INF 0x3f3f3f3f3f3f3f3f
#define inf 0x3f3f3f3f
///vector(len,val);
using namespace std;

typedef long long ll;
typedef double db;
int xx[4] = {1,-1,0,0};
int yy[4] = {0,0,1,-1};
const double eps = 1e-9;
typedef pair<int,int>  P;
const int maxn = 2e6 + 5000;
const ll mod = 1e9 + 7;
inline int sign(db a) { return a < -eps ? -1 : a > eps;}
inline int cmp(db a,db b){ return sign(a - b);}
void debug(int x){  cout << x << endl; }
ll mul(ll a,ll b,ll c) { ll res = 1; while(b) {  if(b & 1) res *= a,res %= c;  a *= a,a %= c,b >>= 1;  }  return res;}
ll phi(ll x) {  ll res = x;  for(ll i = 2; i * i <= x; i++) { if(x % i == 0) res = res / i * (i - 1);   while(x % i == 0) x /= i;   }  if(x > 1) res = res / x  * (x - 1);    return res;}

int fa[maxn];
int Find(int x) {   if(x != fa[x]) return fa[x] = Find(fa[x]);  return fa[x];}
ll c,n,k;
set<P>s;
int main() { int m,t;
    scanf("%d",&t);
    while(t--){   scanf("%d",&n);s.clear();
        for(int i = 1;i <= n * (n - 1) / 2;i++){
            int x;scanf("%d",&x);s.insert(P(x,i));
        }
        vector<int>ans; ans.push_back(0);
        int res = 0;
        while(!s.empty()){
            P p = *s.begin(); res = p.se;
            for(auto d:ans) s.erase(s.upper_bound(P(d + p.fi,-1)));
            ans.push_back(p.fi);
        }
        printf("%d\n",res);
    }
    cerr << "time: " << (long long)clock() * 1000 / CLOCKS_PER_SEC << " ms" << endl;
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值