第 46 屆 ICPC 國際大學生程序設計競賽亞洲區域賽(沈陽)


​ 線上正賽銅尾,有驚無險拿到銅牌,還行,符合預期。
傳送門

E. Edward Gaming, the Champion

​ 題意:從一長串字符串中找出有多少子串是"edgnb"。

​ 題解:簽到題,kmp暴力匹配隨便過,有手就行。

​ edg確實nb

F. Encoded Strings I

​ 題意:……(不好解釋就這樣吧)

​ 題解:就是一個暴力純模擬,按照題意一步步寫就行了。

​ 第一題打得太爽了導致心態有點波動,思考和代碼都有點混亂,調了很久才調出來,導致隊伍掉到了銅牌線外。還是比賽經驗太少了。

B. Bitwise Exclusive-OR Sequence

​ 題意:提供\(n\)個點和\(m\)個關系,每個關系給出\(u,v,w\),代表\(a_u⊕a_v=w\),其中\(⊕\)代表異或計算,找出所有元素滿足關系條件的最小的和,或者說明這樣的元素有無法構造的情況。

​ 題解:有點有關系顯然是圖論題,而且很容易觀察出來這樣的題都是牽一發而動全身(確定一個點即可確定整個圖的情況),因此我們必須從圖的整體入手考慮,以圖為整體進行求解計算。容易把這個圖簡化為\(w=0或1\)的情況;在這種情況下,若\(w=0\)則相鄰兩點相同,反之則不同。我們可以想到二分圖染色的方法來解決這題。

​ 代碼:

#include<bits/stdc++.h>
using namespace std;

struct edge
{
	int u,v,w,nxt;
}e[400003];
int h[200003],etot;

void adde(int u,int v,int w)
{
	e[++etot].u=u,e[etot].v=v,e[etot].w=w,e[etot].nxt=h[u],h[u]=etot;
}

bool v[200003],se[200003];
int cnt[2];

void dfs(int f,int s,int ws,bool sse)
{
	v[s]=1;se[s]=sse;cnt[sse]++;
	for(int i=h[s];i;i=e[i].nxt)
		if(e[i].v!=f)
		{
			int tse=((e[i].w>>ws)&1)?(!sse):sse;
			if(v[e[i].v])
			{
				if(tse!=se[e[i].v])
				{
					cout<<"-1";
					exit(0);
				}
				else
					continue;
			}//visited
			dfs(s,e[i].v,ws,tse);
		}
}

int n,m;

int main()
{
	cin>>n>>m;
	for(int i=1;i<=m;i++)
	{
		int t1,t2,t3;
		scanf("%d%d%d",&t1,&t2,&t3);
		adde(t1,t2,t3);
		adde(t2,t1,t3);
	}
	long long ans=0;
	for(int i=0;i<=30;i++)
	{
		cnt[0]=0,cnt[1]=0;
		memset(v,0,sizeof(v));
		memset(se,0,sizeof(se));
		for(int j=1;j<=n;j++)
		{
			if(!v[j])
				dfs(0,j,i,0);
			ans+=min(cnt[0],cnt[1])*pow(2,i);
			cnt[0]=0,cnt[1]=0;
		}	
	}
	cout<<ans;
	return 0;
}

​ 這題比賽思考和寫代碼都挺順利的,寫完編譯一遍過,樣例一遍過,隊友造的hack一遍過(事實證明隊友沒造好),沒想到還是wa了兩發,而且第二發是在未經仔細思考的情況下直接交的(着實是我自己貢獻的罰時)。本來沒有這么驚險的。

J. Luggage Lock

​ 題意:行李箱上的鎖有四位,一次操作只能使連續的一個或者多個數字向上或者向下移動一次(注意行李箱的數字是循環的而且是從零到九)。給出目前狀態和需要調整到的密碼,問最少用多少次操作。

​ 題解:考場上寫的是一個奇怪的搜索。先是確定差值,然后計算如何最快堆成差值的形狀(堆小山入門題了)。一開始想到的差值只有十六種,以為對於任何一種情況都轉一圈之內才是最好的,但是wa了。改了前后三圈總共差值625種才搜過去,也沒看到底是哪個樣例這么陰間。

​ 代碼:

#include<bits/stdc++.h>
using namespace std;

int a[5],b[5],c[5];
int sgn(int x)
{
	if(x<0) return -1;
	if(x==0) return 0;
	return 1;
}

int getans()
{
	int maxn=0,ans=0;
	for(int i=1;i<=4;i++)
	{
		if(sgn(a[i]==0)) continue;
		else if(sgn(a[i])==sgn(a[i-1])) 
		{
			if(abs(a[i])>maxn)
				ans+=abs(a[i])-maxn;
			maxn=abs(a[i]);
		}
		else  ans+=abs(a[i]),maxn=abs(a[i]);
	}
	return ans;	
}

int reans=9999999;

void dfs(int ws)
{
	if(ws==5)
	{
		reans=min(reans,getans());
	}
	else
	{
		a[ws]=c[ws]-b[ws];
		dfs(ws+1);
		a[ws] -= 10, dfs(ws + 1);
		a[ws] -= 10, dfs(ws + 1);
		a[ws] += 30, dfs(ws + 1);
		a[ws] += 10, dfs(ws + 1);
	}
}

void solve()
{
	int tmp1,tmp2;
	scanf("%d%d",&tmp1,&tmp2);
	for(int i=4;i;i--)
		b[i]=tmp1%10,tmp1/=10;
	for(int i=4;i;i--)
		c[i]=tmp2%10,tmp2/=10;
	
	dfs(1);
	printf("%d\n",reans);
}

int main()
{
	int t;
	cin>>t;
	while(t--)
	{
		reans=9999999;
		solve();	
	}
}

​ 經過四五十種樣例測試全對的我幾乎已經失去希望,但是我的好隊友發現了最后的bug並且完成最后一擊,在此特別感謝我的隊友!

其他題有點難,考察內容不太常考來着,就先這樣吧,期待下周更好的表現。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM