2024.5.31 做題記錄

Limie發表於2024-05-31

1. 外星千足蟲

公元 \(2333\)\(2\)\(3\) 日,在經歷了 \(17\) 年零 \(3\) 個月的漫長旅行後,“格納格魯一號”載人火箭返回艙終於安全著陸。此枚火箭由美國國家航空航天局(NASA)研製發射,行經火星、金星、土衛六、木衛二、穀神星、“張衡星”等 \(23\) 顆太陽系星球,並最終在小行星“傑森星”探尋到了地外生命。宇航員在“傑森星”地表岩層下 \(45.70\) 米位置發現一批珍貴的活體生命樣本,並將其帶回檢測。

在帶回的活體樣本中,最吸引人的當屬這些來自外星的千足蟲了。這些蟲子身軀纖長,身體分為若干節。受到觸碰時,會將身體捲曲成圓環形,間隔一段時間後才會復原活動。

有趣的還不止如此。研究人員發現,這些蟲子的足並不像地球千足蟲成對出現、總共偶數條——它們每節身體下方都有著不定數量的足,但足的總數一定是奇數條!

雖然從外觀難以區分二者,但透過統計足的數目,科學家們就能根據奇偶性判斷出千足蟲所屬的星球。

作為 J 國派去 NASA 的秘密間諜,你希望參加這次研究活動以掌握進一步的情報,而 NASA 選拔的研究人員都是最優秀的科學家。於是 NASA 局長 Charles Bolden 出了一道難題來檢測你的實力:

現在你面前擺有 \(1\ldots N\) 編號的 \(N\) 只千足蟲,你的任務是鑑定每隻蟲子所屬的星球,但不允許親自去數它們的足。

Charles 每次會在這 只千足蟲中選定若干只放入“昆蟲點足機”(the Insect Feet Counter, IFC)中,“點足機”會自動統計出其內所有昆蟲足數之和。Charles 會將這個和數 的結果反饋給你,同時告訴你一開始放入機器中的是哪幾只蟲子。

他的這種統計操作總共進行 \(M\) 次,而你應當儘早得出鑑定結果。

假如在第 \(K\) 次統計結束後,現有資料就足以確定每隻蟲子的身份,你就還應將這個 \(K\) 反饋給 Charles,此時若 \(K<M\),則表明那後 \(M-K\) 次統計並非必須的。

如果根據所有 \(M\) 次統計資料還是無法確定每隻蟲子身份,你也要跟 Charles 講明:就目前資料會存在多個解。

\(1 \le N \le 10^3\)\(1 \le M \le 2 \times 10^3\)


解答

發現這非常高斯消元,但是注意到 \(N\)\(1000\) 所以寄。

發現矩陣為 \(01\) 矩陣,於是 bitset 跑一下。

正確性由於:\({(a \& c)}\)^\({(b \& c)}=(a\)^\(b)\& c\),故顯然。

#include<bits/stdc++.h>
namespace Limie{
	#define x first
	#define y second
	using namespace std;
	typedef long long LL;
	typedef unsigned long long ULL;
	typedef pair<int,int> PII;
}using namespace Limie;
int n,m;
int main()
{
	int i,j,k,c=0;
	cin>>n>>m;
	bitset<1000> a[n],b;
	for(j=1;j<=m;j++){
		string st;char ch;
		cin>>st>>ch;b[n]=ch-'0';
		for(i=0;i<n;i++)b[i]=st[i]-'0';
		for(i=0;i<n;i++){
			if(!b[i])continue;
			if(a[i][i])b^=a[i];else{a[i]=b,c++;break;}
		}
		if(i==n)continue;
		if(c==n){
			cout<<j<<'\n';
			for(j=n-1;j>=0;j--)
				for(k=j+1;k<n;k++)
					if(a[j][k])a[j]^=a[k];
			
			for(j=0;j<n;j++)puts(a[j][n]?"?y7M#":"Earth");
			return 0;
		}
	}puts("Cannot Determine");
}