【2021天梯競技訓練-1】7-7現金入り封筒(25点)


誰もお年玉を奪ったことがないでしょう......ここではN人の間でお年玉を出したり、お年玉を奪ったりした記録を示しています.彼らがお年玉を奪った収穫を統計してください.入力形式:
最初の行に入力すると、正の整数N(≦10 4)が与えられます.すなわち、お年玉を出すこととお年玉を奪うことに参加する人数の合計は、これらの人は1からN番号になります.その後、N行目、i行目には、K N 1 P 1⋯N K K KのうちK(0≦K≦20)はお年玉の個数、N iはお年玉を奪った人の番号、P i(>0)はそのお年玉の金額(分単位)である.注意:同じ人が出したお年玉については、一人当たり最大1回しか奪うことができず、繰り返し奪うことはできません.
出力フォーマット:
所得金額が高い順から低い順に各人の番号と所得金額(元単位で小数点以下2桁)を出力します.1人あたりの情報は1行で、2つの数字の間に1つのスペースがあります.収入金額が並んでいる場合は、現金入り封筒を奪った個数で出力を減らします.並列がある場合は、個人番号で出力を増やします.
サンプルを入力:
10 3 2 22 10 58 8 125 5 1 345 3 211 5 233 7 13 8 101 1 7 8800 2 1 1000 2 1000 2 4 250 10 320 6 5 11 9 22 8 33 7 44 10 55 4 2 1 3 8800 2 1 23 2 123 1 8 250 4 2 121 4 516 7 112 9 10
出力サンプル:
1 11.63 2 3.63 8 3.63 3 2.11 7 1.69 6 -1.67 9 -2.18 10 -3.26 5 -3.26 4 -12.32
コードは次のとおりです.
#include 
using namespace std;

struct person {
     
	int id;  //   
	int get;  //     
	int count;  //       
} p[10001];

bool cmp(person a, person b) {
       //    sort  ,    !! 
	if(a.get != b.get) {
        //             
		return a.get > b.get;
	}
	if(a.count != b.count) {
       //       ,                
		return a.count > b.count;
	}
	return a.id < b.id;  //      ,             
}
int main() {
     
	int n, k, id, money, send[10001] = {
     0};
	cin >> n;
	for(int i = 1; i <= n; i++) {
        //    1 N   
		p[i].id = i, p[i].get = 0, p[i].count = 0;
	}
	for(int i = 1; i <= n; i++) {
     
		cin >> k;
		for(int j = 1; j <= k; j++) {
     
			cin >> id >> money;
			p[id].get += money, p[id].count++;
			send[i] += money;   //         
		}
	}
	for(int i = 1; i <= n; i++) {
     
		p[i].get -= send[i];  //            
	}
	
	sort(p+1, p+n+1, cmp);  //     1   
	for(int i = 1; i <= n; i++) {
     
		printf("%d %.2f
"
, p[i].id, p[i].get/100.0); // !! } return 0; }

心得:
冗長な入力サンプルに驚かないでください.問題の要求をよく見てみると、この問題は一見そんなに難しくありません.sort関数も本当に使いやすいです.c++標準ライブラリのソート関数の使用については、まだよく分からない未熟なパートナーは、ここを参照してください.https://www.cnblogs.com/epep/p/10959627.html