線上正賽銅尾,有驚無險拿到銅牌,還行,符合預期。
傳送門
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並且完成最后一擊,在此特別感謝我的隊友!
其他題有點難,考察內容不太常考來着,就先這樣吧,期待下周更好的表現。
