1. 程式人生 > 其它 >2021.01.19 模擬賽錯題(1)

2021.01.19 模擬賽錯題(1)

貪心

1.零件分組問題。
其實這道題和美元匯率我記得很清楚是網課的時候老師講的,大家還一起討論了,最後我也寫了本題。但是,寫了跟沒寫一樣就很奇怪,一點印象都沒,思路我明白,但卡住的點和我之前寫的時候卡住的是一樣的,但我卻忘了之前是怎麼解決的,淦。這怎麼說,好像只能歸結我沒用心。但我還是自己動腦親手寫的,奇怪。
AC程式碼:

#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
struct node{
	int l, w;
}; node v[10005];//結構體。用這麼多次,終於熟練一點了。 bool cmp(node x, node y){ if (x.l != y.l)return x.l < y.l; return x.w < y.w;//這個比較原理其實還是有點不懂。 } int main(){ int n, xn,yn;//xn為x大小,yn同上。 int res = 0;//答案。 int x[10005] = {}, y[10005] = {}; scanf("%d", &n); for(int i = 1; i <= n; i ++){ scanf("%d %d"
, &v[i].l, &v[i].w); } sort(v + 1, v + 1 + n, cmp);//按長度先排序 for(int i = 1; i <= n; i ++) x[++xn] = v[i].w;//把重量都賦到x數組裡 while(xn > 0){//只要數組裡還有數,就要繼續迴圈。 int maxn = 0; yn = 0; for(int i = 1; i <= xn; i ++){ if(x[i] >= maxn)maxn = x[i];//更新最大值 else y[++yn] = x[i];//新開佇列 } res ++
;//每迴圈完一次,就有一個佇列。 xn = yn;//使x大小變為剩下數的個數 for(int i = 1; i <= xn; i ++)x[i] = y[i];//把新開數組裡的數賦給x數組裡,接著重複操作。 } printf("%d", res); /*for(int i = 1; i <= n; i ++){ for(int j = 1; j <= n; j ++){ if(v[j].w != 0 && v[j].w >= max[i]){ max[i] = v[j].w; v[j].w = 0; } if(v[j].w != 0 && v[j].w < max[i]){ max[i + 1] = v[j].w; v[j].w = 0; } } }註釋掉的這部分是我自己寫的維護佇列。然後計算總佇列數。 大意就是如果重量大於最大值,則替換掉最大值,這個數刪掉。 因為可以存在佇列裡。 如果小於的話就新開一個佇列,最大值存入,這個數刪掉。 最後計算有數的陣列有幾個。 剛剛說到這兒我突然發現這個部分我寫的一個問題, 那就是沒給max[1]賦初值! 不過也不知道賦了會不會好使,總之先說過掉考試的ac程式碼吧。 for(int i = 1; i <= n; i ++){ if(max[i] != 0)c ++; }*/ return 0; }

這道題的收穫:比較的寫法。雖然原理還是不是太明白。

2.合併果子
明白思路,不會寫,請教了學神,藉此也學到不少新東西!!
上AC程式碼!耶!

#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<functional>
#include<vector>
#include<queue>
using namespace std;
int main()
{
	priority_queue<int,vector<int>,greater<int> >q;
	/*
	沒錯!這就是新東西啦!優先佇列!寫法如上,最後的q是佇列的名字。
	greater 可換成 less,此時儲存順序變為由大到小。
	用這個時需要引用幾個庫,那就是後加的仨。
	優先佇列有幾種用法:
	q.push():將元素壓入佇列。
	q.top():
	q.pop():將第一個元素踢出佇列。
	q.empty():判斷佇列是否為空。若為空則輸出1,反之輸出0;
	q.size():判斷佇列有幾個元素。
*/
	int n, ans = 0;
	int a[10005] = {};
	scanf("%d", &n);
	for(int i = 1; i <= n; i ++){
		scanf("%d", &a[i]);
		q.push(a[i]);
	}
	sort(a + 1, a + 1 + n);
	while(q.size()>=2){
		int x = q.top();
		q.pop();
		int y = q.top();
		q.pop();
		ans += x + y;
		q.push(x + y);
	}
	printf("%d", ans);
}

收穫:學習了優先佇列!
(其實剛剛回顧程式碼的時候發現還是有點點不懂while裡的操作)