0%

2025“钉耙编程”中国大学生算法设计暑期联赛(3)

1008—01环

赛时最后靠AI找到了一个hack数据

1
2
3
4
5
6
hack:
1
10
1001010110

ans: 2

就是这个其他时候,交换都是单向的,只有一个选择,但是第一个,交换有两个选择,就都试一下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
ll cal(string &S,char ch){
string origin=S;
S+=S[0];
S+=S[1];
ll ans=0,res=INF;
char chh='0'+((ch-'0')^1);
FOR(i,0,N-1){
char tar= i%2==0?ch:chh;
if(S[i]==tar){
continue;
}
if(i==0){
if(S[N-1]==tar){
swap(S[0],S[N-1]);
S[N]=S[0];
++ans;
continue;
}
}
if(S[i+1]==tar){
swap(S[i],S[i+1]);
if(i==0){
swap(S[N],S[N+1]);
}
ans++;
}else{
S[i]='0'+((S[i]-'0')^1);
if(i==0){
S[N]=S[0];
}
ans++;
}
}
S=origin; // 跑第二遍
res=ans;ans=0;
FOR(i,0,N-1){
char tar= i%2==0?ch:chh;
if(S[i]==tar){
continue;
}
if(S[i+1]==tar){
swap(S[i],S[i+1]);
if(i==0){
swap(S[N],S[N+1]);
}
ans++;
}else{
S[i]='0'+((S[i]-'0')^1);
if(i==0){
S[N]=S[0];
}
ans++;
}
}
res=min(ans,res);
return res;
}

1002小抹爱锻炼

https://acm.hdu.edu.cn/contest/view-code?cid=1174&rid=817

赛时一发就过了。队友的思路,我的代码。

1012核心共振

切比雪夫距离与曼哈顿距离转化+前缀和+队友的公式。

因为有个地方溢出了,WA了一发,改了那个地方就A了。

1007性质不同的数字

其实还好,没有想象中那么神秘,那么这道题目其实是在问不同的区间覆盖情况有几种,那么实际上我们就差分(异或差分)+离散化就行了。

注意这里不能简单+1(下方的代码是对的)(简单的+1就是查lr[i].SE的idx,然后加的地方直接就是idx+1,这个是不行的,我们不能默认这两个区间是相交的)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
vll diff(SZ(li)+5,0);
FOR(i,1,N){
ll l=lower_bound(all(li),lr[i].FI)-li.begin();
ll r=lower_bound(all(li),lr[i].SE+1)-li.begin();
l++,r++;
ll rnd=rng();
diff[l]^=rnd;
diff[r]^=rnd;
}
vll Sum(SZ(li)+5,0);
FOR(i,1,SZ(li)+2){
Sum[i]=Sum[i-1]^diff[i];
}
set<ll> st;
FOR(i,1,SZ(li)+2){
st.insert(Sum[i]);
}
cout<<SZ(st)<<"\n";

1004三带一

sum为牌数总和,ans为答案,rem为剩余牌数sum为牌数总和,ans为答案,rem为剩余牌数

rem=sum3×ansrem=sum-3\times ans 那么剩余的牌的数量一定大于 remansrem\ge ans

tirem(ai3ti)    airem2tit_i\le rem-(a_i-3t_i)\ \ \Rightarrow \ \ a_i-rem\le 2t_i

那么第一个式子没什么难的,剩余的这个rem‘B’肯定要比你的三元组多呀。然后移项一下,这个式子摇身一变,变为了tit_i的下界了,这个好像也挺简单的~~(就是赛时想不到)~~。

然后向上取整除法的写法需要特判<0的情况,因为众所周知,C++的/是向0取整的,

1
2
3
4
5
inline ll chu(ll x){
if(x<0) return x/2;
if(x%2==0) return x/2;
return x/2+1;
}

check函数的写法,这个low怎么说呢,也没啥物理意义,就是纯数学推出来的式子,你就说是不是下界吧()。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
auto check=[&](ll ans)->bool{
// 剩余多少个AAAB中的‘B’
ll rem=sum-3*ans;
if(rem<ans){ // 剩余的‘B’都不够,巧妇难为无米之炊
return false;
}
ll high=0,slow=0;
FOR(i,1,13){
ll lhigh=A[i]/3;
ll low=chu(A[i]-rem);
if(low>lhigh){
return false;
}
high+=lhigh;
slow+=max(0ll,low);
}
if(high>=ans && ans>=slow){
return true;
}
return false;
};

https://acm.hdu.edu.cn/contest/view-code?cid=1174&rid=22887

1009线段染色

https://acm.hdu.edu.cn/contest/problem?cid=1174&pid=1009

又是沟槽的概率题目。

感觉不是我能碰瓷的题目,之后有兴趣了再来看吧。

https://grok.com/chat/dc6a06d2-50d6-4bb8-a88b-87a1c553307d