2025“钉耙编程”中国大学生算法设计春季联赛(2)(2 4 5,补3 6 8)

2025“钉耙编程”中国大学生算法设计春季联赛(2)(2 4 5,补3 6 8)

1002:烂人方法

include<bits/stdc++.h>

define N 1005

define mod 998244353

using namespace std;
typedef long long ll;
string a[] = {"jia","yi","bing","ding","wu","ji","geng","xin","ren","gui","jia","yi","bing","ding","wu","ji","geng","xin","ren","gui","jia","yi","bing","ding","wu","ji","geng","xin","ren","gui","jia","yi","bing","ding","wu","ji","geng","xin","ren","gui","jia","yi","bing","ding","wu","ji","geng","xin","ren","gui","jia","yi","bing","ding","wu","ji","geng","xin","ren","gui","jia","yi","bing","ding","wu","ji","geng","xin","ren","gui"};
//string b[] = {"zi","chou","yin","chen","si","wu","wei","shen","you","xv","hai","zi","chou","yin","chen","si","wu","wei","shen","you","xv","hai","zi","chou","yin","chen","si","wu","wei","shen","you","xv","hai","zi","chou","yin","chen","si","wu","wei","shen","you","xv","hai","zi","chou","yin","chen","si","wu","wei","shen","you","xv","hai","zi","chou","yin","chen","si","wu","wei","shen","you","xv","hai","zi","chou","yin","chen","si","wu","wei","shen","you","xv","hai""zi","chou","yin","chen","si","wu","wei","shen","you","xv","hai","zi","chou","yin","chen","si","wu","wei","shen","you","xv","hai","zi","chou","yin","chen","si","wu","wei","shen","you","xv","hai"};
string b[] = {"zi","chou","yin","mao","chen","si","wu","wei","shen","you","xu","hai","zi","chou","yin","mao","chen","si","wu","wei","shen","you","xu","hai","zi","chou","yin","mao","chen","si","wu","wei","shen","you","xu","hai","zi","chou","yin","mao","chen","si","wu","wei","shen","you","xu","hai","zi","chou","yin","mao","chen","si","wu","wei","shen","you","xu","hai","zi","chou","yin","mao","chen","si","wu","wei","shen","you","xu","hai","zi","chou","yin","mao","chen","si","wu","wei","shen","you","xu","hai"};
void solve()
{
string s;
cin>>s;
int i = 0;
while(1)
{
string c;
c = a[i]+b[i];
//cout<<c;
if(c == s)
{
cout<<1984+i<<"\n";
return;
}
i++;
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int T = 1;
cin>>T;
while(T--)
solve();
return 0;
}

1004:暴力dp

include<bits/stdc++.h>

define N 1005

define mod 998244353

using namespace std;
typedef long long ll;
int f[10005];
void solve()
{
string s1,s2;
cin>>s1>>s2;
int u = 0;
if(s2.size() <= 2)
{
while(!s2.empty())
{
u*=10;
u += s2[0]-'0';
s2.erase(0,1);
}
if(u >= 26)
{
map<char,int>mp;
for(int i = 0;i < s1.size();i++)
{
if(mp[s1[i]]) mp[s1[i]]++;
}
cout<<mp.size()<<"\n";
}
else
{
string s;
while(u--)
{
s+=s1;
}
int ans = 0;
for(int i = 0;i < s.size();i++)
{
f[i] = 1;
for(int j = 0;j < i;j++)
{
if(s[j] < s[i]) {f[i] = max(f[i],f[j]+1);}
}
}
for(int i = 1;i < s.size();i++) ans = max(ans,f[i]);
cout<<ans<<"\n";
}
}
else
{
map<char,int>mp;
for(int i = 0;i < s1.size();i++)
{
if(mp[s1[i]]) mp[s1[i]]++;
}
cout<<mp.size()<<"\n";
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int T = 1;
cin>>T;
while(T--)
solve();
return 0;
}

1005:理性分析

idea:

如果 ( k ) 是奇数,则答案为 0。

先讨论 ( k = 2 ) 的情形,此时有 ( \lceil n/2 \rceil ) 条平行 ( l_0 ) 的直线和 ( \lfloor n/2 \rfloor ) 条垂直 ( l_0 ) 的直线,答案就是二者的积。

对于 ( k > 2 ) 的情形,可以把所有 ( l_i ) 按照 ( i \mod (k/2) ) 分组,此时有 ( n \mod (k/2) ) 组直线有 ( \lfloor n/k \rfloor + 1 ) 条,另外 ( (k/2) - (n \mod (k/2)) ) 组直线有 ( \lfloor n/k \rfloor ) 条。显然垂直的直线都在同一个组内,并且每一个组自身都是一个 ( k = 2 ) 的情形,套用上面的结论即可。

include<bits/stdc++.h>

define N 1005

define mod 998244353

using namespace std;
typedef long long ll;

void solve()
{
int n,k;
cin>>n>>k;
if(k%2!=0)
{
cout<<0<<"\n";
return ;
}
ll m = k/2;
if(m > n-1)
{
cout<<0<<"\n";
return ;
}
ll q = (n-1)/m;
ll maxj = (q-1)/2;
if(maxj < 0)
{
cout<<0<<"\n";
return ;
}
ll cnt = maxj+1;
ll ans = cntn-mcnt*cnt;
cout<<ans<<"\n";
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int T = 1;
cin>>T;
while(T--)
solve();
return 0;
}

1003:

idea:关键在于找到第三个数字使得(p,0,p,q)能够为答案做出贡献,所以可以用从后往前map来记录一个数字首次出现的位置。再次从前往后遍历,如果p出现了超过两次,那么拿他首次出现位置和目前0的位置比较,如果x[p]<0,那么他就对答案做出贡献,其贡献即为当前>0的数字的后缀和,同时把当前的x[p]标记为inf,那么后面再次遍历到p的时候其则没有贡献

注意:这里的关键从后往前遍历找p首先出现的位置以及从前往后遍历0的位置,如果p只出现一次(后面即使有0,mp[a[i]]也不会再次出现)或者0的位置没有更新,那么p对答案不产生贡献

include<bits/stdc++.h>

define mod 998244353

using namespace std;
typedef long long ll;
const int N = 1e9+7;
int cnt[1000005];
void solve()
{
ll n;
memset(cnt,0,sizeof(cnt));
cin>>n;
vectora(n+1);//1 1 1 1 0 1 3 1 0 1 2 2 0 2 2 3 5 7 8 9 1 0 2 2 0 0
for(int i = 1;i <= n;i++) cin>>a[i];
unordered_map<int,int>mp;
int last0 = 0;
vectorans(n+2,0);
for(int i = n;i >= 1;i--)
{
if(a[i] == 0)
{
ans[i] = ans[i+1];
continue;
}
ans[i] = ans[i+1] + (mp[a[i]]==0);
//cnt[a[i]] = i;
mp[a[i]] = i;
}
ll res = 0;
for(int i = 1;i <= n;i++)
{
if(a[i] == 0)
{
last0 = i;
continue;
}
if(mp[a[i]] < last0)
{
res += ans[i+1];
mp[a[i]] = N;
}
}
cout<<res<<"\n";
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int T = 1;
cin>>T;
while(T--)
solve();
return 0;
}

1006:博弈论,guess题

推荐佬的博客【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(2) - 天天超方的 - 博客园

include<bits/stdc++.h>

using namespace std;
typedef long long ll;

void solve()
{
ll n,m,k;
cin>>n>>m>>k;
if((n+2*m)%4) cout<<"Alice\n";
else cout<<"Bob\n";
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr),cout.tie(nullptr);
int T = 1;
cin>>T;
while(T--)
{
solve();
}
}

1008:拓扑,图

ieda:首先每个点只有3种可能的颜色ac2ef8459f28471f9dd3f1c43fe1e99d

至于怎么推的我也guess了半天,如果某个块出现了直接no即可

如果都成立,那么这个点一定是属于后面的状态(即是最后一次经过的)此时只需要从另外两种颜色向这个颜色连一条边,表示这个点是后面经过的

最后进行拓扑排序,如果存在环,那么则不满足条件

include<bits/stdc++.h>

define N 100005

define mod 998244353

using namespace std;
typedef long long ll;
#define int long long

void solve()
{
int n,k;
cin>>n>>k;
vector<vector>g(3n+1);
vectorin(3
n+1,0);
bool ok = 1;
while(k--)
{
int x,y,z;
cin>>x>>y>>z;
int q = (y+1)/2,p = 2n-x+1,r = 2n+x-y/2;
if(!ok) continue;
if(z!=q && z!=p && z!=r)
{
ok = 0;
continue;
}
if(z == q)
{
g[r].push_back(z);
g[p].push_back(z);
}
else if(z == p)
{
g[q].push_back(z);
g[r].push_back(z);
}
else if(z == r)
{
g[q].push_back(z);
g[p].push_back(z);
}
in[z] += 2;
}
if(!ok)
{
cout<<"No\n";
return ;
}
auto tuopu = &
{
queueq;
for(int i = 1;i <= 3n;i++)
{
if(!in[i])
{
q.push(i);//找到入度为0的点
}
}
while(!q.empty())
{
int now = q.front();
q.pop();
for(auto &i:g[now])
{
if((--in[i]) == 0)
{
q.push(i);
}
}
}
for(int i = 1;i <= 3
n;i++)
{
if(in[i]) return false;
}
return true;
};
if(tuopu()) cout<<"Yes\n";
else cout<<"No\n";
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int T = 1;
cin>>T;
while(T--)
solve();
return 0;
}

posted @ 2025-03-18 20:59  graspppp  阅读(97)  评论(0)    收藏  举报