Avito Cool Challenge 2018 B - Farewell Party

题目大意:

有n个人

接下来一行n个数a[i] 表示第i个人描述其他人有a[i]个的帽子跟他不一样

帽子编号为1~n 如果所有的描述都是正确的

输出possible 再输出一行b[i] 表示第i个人的帽子的编号

如果存在矛盾 输出impossible

如果存在p 个人都描述有q个人跟他们的帽子不一样

此时若 p+q=n 说明正确且这p个人的帽子都一样

a[] = 3 3 2 2 2 ,此时一种解为 b[] = 1 1 2 2 2

存在p=2个人描述有q=3个人跟他们不一样 说明这两个人的帽子编号是一样的

但是这种方法存在一种特殊情况

a[] = 4 4 4 4 4 4 ,如果按上面的解法此时则无解

但是实际上存在一种解 即 b[] = 1 1 2 2 3 3

不过可以看出来这种特殊情况 每种帽子对应的人数是一样多的

那么此时存在p=6个人描述有q=4个人跟他们不一样

?可以得到每种帽子对应人数为 t

判断一下p能不能整除t 若能说明描述正确

否则 描述矛盾 impossible

题目要求对应第i个人输出帽子编号  。。英语渣给跪了 错在这里以为不需要对应

不需要对应很好处理 需要对应其实也不难

开了一排栈~

第一种情况 在ans[q]压入一种编号p个

特殊情况 在ans[q]压入p/t种编号t个

最后从每个人的描述arr[i]里取ans[arr[i]]的栈顶输出就行了

#include <bits/stdc++.h>
#define LL long long
#define INF 0x3f3f3f3f
using namespace std;
int n, arr[100005];
stack <int> ans[100005];
int main()
{
    while(~scanf("%d",&n)) {
        for(int i=1;i<=n;i++)
            while(!ans[i].empty())
                ans[i].pop();
        map <int,int> mp; mp.clear();
        for(int i=0;i<n;i++) {
            scanf("%d",&arr[i]);
            if(!mp.count(arr[i])) mp[arr[i]]=1;
            else mp[arr[i]]++; // 记录描述为q的人有多少个
        }
        map <int,int> :: iterator it;
        bool OK=1; int id=1;
        for(it=mp.begin();it!=mp.end();it++) {
            int q=(*it).first, p=(*it).second;
            if(p+q!=n) {
                int t=n-q;
                if(p%t==0) { // 特殊情况
                    for(int i=0;i<p/t;i++) { // 压入p/t种
                        for(int j=0;j<t;j++) // 每种t个
                            ans[q].push(id);
                        id++;
                    }
                } else {
                    OK=0; break;
                }
            }
            else { //
                while(p--) ans[q].push(id); // 压入一种编号p个
                id++;
            }
        }
        if(OK) {
            printf("Possible\n");
            for(int i=0;i<n;i++) {
                printf("%d ",ans[arr[i]].top());
                ans[arr[i]].pop();
            } printf("\n");
        } else printf("Impossible\n");
    }

    return 0;
}

原文地址:https://www.cnblogs.com/zquzjx/p/10129721.html

时间: 2024-10-31 21:42:31

Avito Cool Challenge 2018 B - Farewell Party的相关文章

Codeforces Avito Code Challenge 2018 D. Bookshelves

Codeforces Avito Code Challenge 2018 D. Bookshelves 题目连接: http://codeforces.com/contest/981/problem/D Description Mr Keks is a typical white-collar in Byteland. He has a bookshelf in his office with some books on it, each book has an integer positive

Avito Cool Challenge 2018 A. B题解

A. Definite Game 题目链接:https://codeforces.com/contest/1081/problem/A 题意: 给出一个数v,然后让你可以重复多次减去一个数d,满足v%d!=0,问最后可以得到最小的是多少. 题解: 除开v=2输出2,其余直接输出1就行了= =/ 代码如下: #include <bits/stdc++.h> using namespace std; int main(){ int v; cin>>v; cout<<(v==

Avito Cool Challenge 2018 Solution

A. Definite Game 签. 1 #include <bits/stdc++.h> 2 using namespace std; 3 4 int main() 5 { 6 int a; 7 while (scanf("%d", &a) != EOF) 8 { 9 [](int x) 10 { 11 for (int i = x - 1; i >= 1; --i) if (x % i) 12 { 13 printf("%d\n",

cf掉分记——Avito Code Challenge 2018

再次作死的打了一次cf的修仙比赛感觉有点迷.. 还好掉的分不多(原本就太低没法掉了QAQ) 把会做的前三道水题记录在这.. A: Antipalindrome emmmm...直接暴力枚举 code: //By Menteur_Hxy #include <cstdio> #include <iostream> #include <algorithm> #include <cstring> using namespace std; int n,ans; cha

[Avito Code Challenge 2018 G] Magic multisets(线段树)

题目链接:http://codeforces.com/contest/981/problem/G 题目大意: 有n个初始为空的‘魔法’可重集,向一个‘可重集’加入元素时,若该元素未出现过,则将其加入:否则该可重集中所有元素的个数都会翻倍. 例如将$2$加入${1,3}$会得到${1,2,3}$,将$2$加入${1,2,3,3}$会得到${1,1,2,2,3,3,3,3}$. $q$次操作,每次操作要么向一个区间内的所有可重集加入某个元素,要么询问一个区间内可重集的大小之和. $n,q ≤ 2×1

Avito Cool Challenge 2018:C. Colorful Bricks

C. Colorful Bricks 题目链接:https://codeforces.com/contest/1081/problem/C 题意: 有n个横向方块,一共有m种颜色,然后有k个方块的颜色与其左边的颜色不同(第一个除外),问一共有多少染色方案. 题解: 我们首先来考虑一下dp. 设dp(i,j)为当前第i个方块,一共有j个方块与它前面的方块不同的方案个数. 那么转移方程为dp(i,j)=dp(i-1,j-1)*(m-1)+dp(i-1,j). 代码如下: #include <bits

Avito Cool Challenge 2018:D. Maximum Distance (最小生成树)

题目链接 题意 : 给出一个联通图和一些特殊的点,现在定义cost(u,v)为一条从u到v的路径上面边权的最大值 , 定义dis(u,v) 为从u到v 路径上面cost 的最小值 然后求所有特殊点到其他特殊点的最大距离 题解: 做这题前,首先思考一件事情,对于一颗树来说点到点的距离是不是就是树上面路径的边权最大值 我们来证明一下:假设在最小生成树上面的路径cost为w1,另外在原图中还有一条路径从u到v,其cost为w2,那么必然有w2>w1的.那么我们最后的dis一定是w1. 那么我们现在的目

Codechef October Challenge 2018 游记

Codechef October Challenge 2018 游记 CHSERVE - Chef and Serves 题目大意: 乒乓球比赛中,双方每累计得两分就会交换一次发球权. 不过,大厨和小厨用了另外一种规则:双方每累计得 K 分才会交换发球权.比赛开始时,由大厨发球. 给定大厨和小厨的当前得分(分别记为 P1 和 P2),请求出接下来由谁发球. 思路: \((P1+P2)\%K\)判断奇偶性即可. 代码链接 BITOBYT - Byte to Bit 题目大意: 在字节国里有三类居民

June Challenge 2018 Division 2

Naive Chef 暴力 1 #include <bits/stdc++.h> 2 using namespace std; 3 4 int main() { 5 int T; 6 scanf("%d", &T); 7 while(T--){ 8 int N, A, B, x, ca = 0, cb = 0; 9 scanf("%d %d %d", &N, &A, &B); 10 for(int i = 1; i <