赛时解决题目:A,B,H
目录
H:
题意:抽卡游戏,签到题
解题思路:记录10连出四星以上,90连出保底,还有大保底判一下就行。
#include<bits/stdc++.h>
#define endl '\n'
#define ll long long
#define int long long
#define double long double
#define Int __int128
#define pb push_back
#define MAX_LOG 21
#define ff first
#define ss second
#define M 5005
#define ull unsigned long long
using namespace std;
const double PI=3.1415926535897932385;
const ll LLMAX=9223372036854775807ll;
const ll LLMIN=-9223372036854775808ll;
//const int MAX_INT=0x3f3f3f3f;
const int IIMAX=2147483647;
const int IIMIN=-2147483648;
const int INF=0x3f3f3f3f;
typedef pair<ll,ll> PLL;
ll gcd(ll a,ll b)
{
if(b) while((a%=b)&&(b%=a));
return a+b;
}//最大公约数函数
ll spid(ll a,ll b,ll p)
{
ll ans=1;
while(b)
{
if(b&1)ans=ans*a%p;
b>>=1;
a=a*a%p;
}
return ans;
}//快速幂函数
///泡沫在阳光下闪烁,像星辰在寂静得夜空中闪耀
///秋雨
const ll N=2e5+10;
void solve()
{
string s;cin>>s;
ll a[6]={0};
ll cnt90=0,cnt10=0;
bool ret=0;
ll ans=1;
for(auto i:s)
{
cnt90++;
cnt10++;
if(i=='4'||i=='5'||i=='U')cnt10=0;
if(i=='5')
{
if(ret==1)
{
ans=0;break;
}else
ret=1,cnt90=0;
}
if(i=='U')
{
cnt90=0;
ret=0;
}
if(cnt90==90||cnt10==10)ans=0;
}
if(ans)
cout<<"valid\n";
else cout<<"invalid\n";
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int t=1;
cin>>t;
while(t--)
{
solve();
}
}
///在秋天邂逅, 在春天发芽,在夏天壮大,在秋天萧瑟,在冬天萎缩,
///而后,春天再度归来。
B:
题意:奶奶买了一个大蛋糕。蛋糕的形状是正多边形。也就是说,一个所有内角相等且所有边相等的凸多边形。奶奶想把蛋糕切成一个漂亮的图案,和她的朋友们分享。她以逆时针的顺序将顶点0到n - 1编成索引,然后选择一个整数k。之后,她将蛋糕切割成n条直线,将顶点i和顶点(i+k)连接起来,每个i mod n。请帮她算一下。(有道翻译)
解题思路:模拟一下发现就是正多边形,然后按照规律割线,注意一下会发现k肯定具有对称性,因此可以让k小于n的一半,又发现如果穿过中心点,是一种特殊情况,且只会出现在偶数正多边形,进行特判,最后手动模拟一下,k为2~n/2,会发现k每次加一,画出来的图就会多n块,结论就出来了。
#include<bits/stdc++.h>
#define endl '\n'
#define ll long long
#define int long long
#define double long double
#define Int __int128
#define pb push_back
#define MAX_LOG 21
#define ff first
#define ss second
#define M 5005
#define ull unsigned long long
using namespace std;
const double PI=3.1415926535897932385;
const ll LLMAX=9223372036854775807ll;
const ll LLMIN=-9223372036854775808ll;
//const int MAX_INT=0x3f3f3f3f;
const int IIMAX=2147483647;
const int IIMIN=-2147483648;
const int INF=0x3f3f3f3f;
typedef pair<ll,ll> PLL;
ll gcd(ll a,ll b)
{
if(b) while((a%=b)&&(b%=a));
return a+b;
}//最大公约数函数
ll spid(ll a,ll b,ll p)
{
ll ans=1;
while(b)
{
if(b&1)ans=ans*a%p;
b>>=1;
a=a*a%p;
}
return ans;
}//快速幂函数
///泡沫在阳光下闪烁,像星辰在寂静得夜空中闪耀
///秋雨
const ll N=2e5+10;
void solve()
{
ll n;cin>>n;
ll k;cin>>k;
if(k>n/2)
{
k=n-k;
}
if(n%2==0&&k==n/2)
{
cout<<n<<'\n';
}else
{
ll ans=n+1;
ans+=(k-1)*n;
cout<<ans<<'\n';
}
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int t=1;
while(t--)
{
solve();
}
}
///在秋天邂逅, 在春天发芽,在夏天壮大,在秋天萧瑟,在冬天萎缩,
///而后,春天再度归来。
A:
题意:(我也没想过这题目信息量挺大),有A人和B人两个人分蛋糕,然后他们有个分蛋糕的方式,首先给一棵现成的树,根节点为1,给你n个点,和n-1条边,边权值要么是1要么是0。两个人轮流走,A先走,从根节点开始,选取当前点的子节点中的一个,捡起边权值1或0,直到走到终点。这样把路径上的1,0拼起来成了一个01字符串,长度假设为m。那么这时B人要把蛋糕任意切成m份(也可以是空的几份),然后两个人按照01字符串的规则,如果是数字1,那么A人从分出来的蛋糕中挑一块,如果是0则B去挑一块。问A人最多能吃蛋糕几分之几。
解题思路:A肯定希望早拿和多拿1,B也是,那么dfs跑一下就行,对于每个01串,ans只需要取个min即可,因为蛋糕是由B去切成块的,而他们肯定都先拿大的,所以B肯定切出来是均等的有效块数。那么对于每轮进行贪心,A想要ans大,B想要ans小,递归即可。
#include<bits/stdc++.h>
#define endl '\n'
#define ll long long
#define int long long
#define double long double
#define Int __int128
#define pb push_back
#define eb emplace_back
#define MAX_LOG 21
#define ff first
#define ss second
#define M 5005
#define ull unsigned long long
using namespace std;
const double PI=3.1415926535897932385;
const ll LLMAX=9223372036854775807ll;
const ll LLMIN=-9223372036854775808ll;
//const int MAX_INT=0x3f3f3f3f;
const int IIMAX=2147483647;
const int IIMIN=-2147483648;
const int INF=0x3f3f3f3f;
typedef pair<ll,ll> PLL;
ll gcd(ll a,ll b)
{
if(b) while((a%=b)&&(b%=a));
return a+b;
}//最大公约数函数
ll spid(ll a,ll b,ll p)
{
ll ans=1;
while(b)
{
if(b&1)ans=ans*a%p;
b>>=1;
a=a*a%p;
}
return ans;
}//快速幂函数
///泡沫在阳光下闪烁,像星辰在寂静得夜空中闪耀
///秋雨
const ll N=2e5+10;
ll a[N];
vector<ll>go[N];
map<PLL,ll>mp;
double dfs(ll u,ll fa,ll ret,double cnt0,double cnt1,double ans)
{
if(cnt0+cnt1>=1)ans=min(ans,cnt1/(cnt0+cnt1));
double res=ans;
if(go[u].empty())
{
return res;
}
bool ru=0;
for(auto i:go[u])
{
if(i==fa)continue;
if(!ru)
{
if(ret)ans=dfs(i,u,ret^1,cnt0+(mp[{min(u,i),max(i,u)}]==0),cnt1+(mp[{min(u,i),max(i,u)}]==1),res);
else ans=dfs(i,u,ret^1,cnt0+(mp[{min(u,i),max(i,u)}]==0),cnt1+(mp[{min(u,i),max(i,u)}]==1),res);
ru=1;
continue;
}
if(ret)ans=max(dfs(i,u,ret^1,cnt0+(mp[{min(u,i),max(i,u)}]==0),cnt1+(mp[{min(u,i),max(i,u)}]==1),res),ans);
else ans=min(dfs(i,u,ret^1,cnt0+(mp[{min(u,i),max(i,u)}]==0),cnt1+(mp[{min(u,i),max(i,u)}]==1),res),ans);
}
res=ans;
return res;
}
void solve()
{
ll n;
cin>>n;
for(int i=1; i<=n; i++)a[i]=0,go[i].clear();
for(int i=1; i<n; i++)
{
ll u,v,w;
cin>>u>>v>>w;
if(u>v)swap(u,v);
go[u].eb(v);
go[v].pb(u);
mp[{u,v}]=w;
}
cout<<fixed<<setprecision(13)<<dfs(1,-1,1,0,0,1)<<'\n';
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int t=1;
cin>>t;
while(t--)
{
solve();
}
}
///在秋天邂逅, 在春天发芽,在夏天壮大,在秋天萧瑟,在冬天萎缩,
///而后,春天再度归来。
F:图论(构造)
题意:给一个树林,然后问这树林的补图存不存在哈密尔顿路径。
哈密尔顿路径:经过所有点,且每个点只经过一次。
补图:补图中存在边的两点,在原图中不存在边。
解题思路:会发现点数在2,3时需要特判一下,剩下的必然树的直径是大于4的,那么可以根据深度进行分层,会发现奇数层和偶数层可以几乎任意的去接,而同一层的点也可以随意接在一起(因为题目保证没有环)。这时候就需要判断一下只有一圈的菊花图,因为连完树枝后,没有点可以连到中点,但因为题目是树林,所以可以把这个点接到下一棵树的脑袋上。
#include<bits/stdc++.h>
#define endl '\n'
#define ll long long
#define int long long
#define double long double
#define Int __int128
#define pb push_back
#define eb emplace_back
#define N (int)3e5+10
#define MAX_LOG 21
#define ff first
#define ss second
#define M 5005
#define ull unsigned long long
using namespace std;
const double PI=3.1415926535897932385;
const ll LLMAX=9223372036854775807ll;
const ll LLMIN=-9223372036854775808ll;
//const int MAX_INT=0x3f3f3f3f;
const int IIMAX=2147483647;
const int IIMIN=-2147483648;
const int INF=0x3f3f3f3f;
typedef pair<ll,ll> PLL;
ll gcd(ll a,ll b)
{
if(b) while((a%=b)&&(b%=a));
return a+b;
}//最大公约数函数
ll spid(ll a,ll b,ll p)
{
ll ans=1;
while(b)
{
if(b&1)ans=ans*a%p;
b>>=1;
a=a*a%p;
}
return ans;
}//快速幂函数
///泡沫在阳光下闪烁,像星辰在寂静得夜空中闪耀
///秋雨
void solve()
{
int n,m;
cin>>n>>m;
vector<vector<int>>G(n+1);
for(int i=0;i<m;i++)
{
int x,y;
cin>>x>>y;
G[x].eb(y);
G[y].eb(x);
}
if(n==2)
{
if(m==0)
cout<<"1 2\n"; /// 补图是唯一的哈密尔顿路径
else
cout<<"-1\n";
}
else if(n==3)
{
if(m==0)
cout<<"1 2 3\n";
else if(m==2)
{
cout<<"-1\n";
}
else if(m==1)
{
if(G[1].size()&&G[3].size())
{
cout<<"1 2 3\n";
}
else if(G[1].size()&&G[2].size())
{
cout<<"1 3 2\n";
}
else if(G[2].size()&&G[3].size())
{
cout<<"2 1 3\n";
}
}
}
else // n>=4
{
vector<int>vis(n+1),dist(n + 1);
int mxidx=0;
auto dfs=[&](auto self,int u,int fa)->void
{
if(dist[u]>dist[mxidx])mxidx=u;
vis[u]=true;
for(auto it:G[u])
{
if(it==fa)
continue;
else
{
dist[it]=dist[u]+1LL;
self(self,it,u);
}
}
};
vector<PLL>v;
for(int i=1;i<=n;i++)
{
if(!vis[i])
{
mxidx=i;
dfs(dfs,i,0ll);
dist[mxidx]=0ll;
int u=mxidx;
dfs(dfs,mxidx,0ll);
v.push_back({u,mxidx});
}
}
auto add=[&](int u,int v)->void
{
G[u].eb(v);
G[v].eb(u);
};
for (int i=1;i<v.size();i++)
{
add(v[i-1].ss,v[i].ff);
}
dist[v[0].ff] = 0;
mxidx=v[0].ff;
dfs(dfs,mxidx,0);
int I=dist[mxidx]+1LL;
if (I<=3)
{
cout<<"-1\n";
}
else
{
vector<vector<int>>VE(dist[mxidx]+2LL);
for(int i=1;i<=n;i++)VE[dist[i]+1LL].eb(i);
for (int i=I-1;i>=1;i-=2)
{
for (auto x:VE[i])cout<<x<< " ";
}
for (int i=I;i>=1;i-=2)
{
for (auto x:VE[i])cout<<x<<" ";
}
cout<<"\n";
}
}
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int t=1;
cin>>t;
while(t--)
{
solve();
}
}
///在秋天邂逅, 在春天发芽,在夏天壮大,在秋天萧瑟,在冬天萎缩,
///而后,春天再度归来。
D:tanjan
解题:(我去学了一波tanjan(强连通分量),交了洛谷的板子题),下面是洛谷题的代码:消息扩散
#include<bits/stdc++.h>
#define endl '\n'
#define ll int
#define int int
#define double long double
#define Int __int128
#define pb push_back
#define eb emplace_back
#define MAX_LOG 21
#define ff first
#define ss second
#define M 5005
#define ull unsigned long long
using namespace std;
const double PI=3.1415926535897932385;
const ll LLMAX=9223372036854775807ll;
const ll LLMIN=-9223372036854775808ll;
//const int MAX_INT=0x3f3f3f3f;
const int IIMAX=2147483647;
const int IIMIN=-2147483648;
const int INF=0x3f3f3f3f;
typedef pair<ll,ll> PLL;
typedef pair<int,int>PII;
ll gcd(ll a,ll b)
{
if(b) while((a%=b)&&(b%=a));
return a+b;
}//最大公约数函数
ll spid(ll a,ll b,ll p)
{
ll ans=1;
while(b)
{
if(b&1)ans=ans*a%p;
b>>=1;
a=a*a%p;
}
return ans;
}//快速幂函数
///泡沫在阳光下闪烁,像星辰在寂静得夜空中闪耀
///秋雨
const ll N=2e5+10;
vector<ll>go[N];
ll dfn[N];
ll cnt;
stack<ll>st;
ll vis[N];///看某个点是否入栈
ll low[N];
ll _cnt;
ll sum[N];///强连通分量权值记录
ll belong[N];///该点属于哪个强连通分量
ll sig[N];///强连通分量可到标记点
void tanjan(ll u)
{
cnt++;
dfn[u]=low[u]=cnt;
st.push(u);
vis[u]=1;
for(auto i:go[u])
{
if(dfn[i]==0)
{
tanjan(i);
low[u]=min(low[u],low[i]);
}
else if(vis[i])///如果i在栈中,那么i一定是u的祖先节点
{
low[u]=min(low[u],dfn[i]);
}
}
if(low[u]==dfn[u])
{
_cnt++;
while(st.top()!=u)
{
sum[_cnt]++;///加的是权值
vis[st.top()]=0;
belong[st.top()]=_cnt;
st.pop();
}
sum[_cnt]++;///他本身的权值
belong[u]=_cnt;
vis[u]=0;
st.pop();
}
}
void solve()
{
ll n,m;cin>>n>>m;
for(int i=1;i<=m;i++)
{
ll u,v;cin>>u>>v;
go[u].pb(v);
};
for(int i=1;i<=n;i++)
{
if(!dfn[i])
tanjan(i);
}
for(int u=1;u<=n;u++)
{
for(auto v:go[u])
{
if(belong[u]!=belong[v])
{
sig[belong[v]]=1;
}
}
}
ll ans=0;
// cout<<_cnt<<'\n';
for(int i=1;i<=_cnt;i++)
{
ans+=(sig[i]==0);
}
cout<<ans<<'\n';
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int t=1;
// cin>>t;
while(t--)
{
solve();
}
}
///在秋天邂逅, 在春天发芽,在夏天壮大,在秋天萧瑟,在冬天萎缩,
///而后,春天再度归来。
这边放D题AC代码
#include<bits/stdc++.h>
#define endl '\n'
#define ll long long
#define int long long
#define double long double
#define Int __int128
#define pb push_back
#define eb emplace_back
#define MAX_LOG 21
#define ff first
#define ss second
#define M 5005
#define ull unsigned long long
using namespace std;
const double PI=3.1415926535897932385;
const ll LLMAX=9223372036854775807ll;
const ll LLMIN=-9223372036854775808ll;
//const int MAX_INT=0x3f3f3f3f;
const int IIMAX=2147483647;
const int IIMIN=-2147483648;
const int INF=0x3f3f3f3f;
typedef pair<ll,ll> PLL;
typedef pair<int,int>PII;
ll gcd(ll a,ll b)
{
if(b) while((a%=b)&&(b%=a));
return a+b;
}//最大公约数函数
ll spid(ll a,ll b,ll p)
{
ll ans=1;
while(b)
{
if(b&1)ans=ans*a%p;
b>>=1;
a=a*a%p;
}
return ans;
}//快速幂函数
///泡沫在阳光下闪烁,像星辰在寂静得夜空中闪耀
///秋雨
const ll N=2e5+10;
vector<ll>go[N];
ll dfn[N];
ll cnt;
stack<ll>st;
ll ins[N];///看某个点是否入栈
ll low[N];
ll _cnt;
ll sum[N];///强连通分量权值记录
ll belong[N];///该点属于哪个强连通分量
ll sig[N];///强连通分量可到标记点
ll n,m;
vector<PLL>lun;
vector<PLL>qie;
vector<PLL>ans;
void tanjan(ll u,ll fa)
{
cnt++;
dfn[u]=low[u]=cnt;
st.push(u);
ins[u]=1;
for(auto i:go[u])
{
// cout<<"r="<<i<<'\n';
if(i==fa)continue;
if(dfn[i]==0)
{
tanjan(i,u);
low[u]=min(low[u],low[i]);
}
else if(ins[i]==1)///如果i在栈中,那么i一定是u的祖先节点
{
low[u]=min(low[u],dfn[i]);
}
}
if(low[u]==dfn[u])
{
_cnt++;
while(st.top()!=u)
{
sum[_cnt]++;///加的是权值
ins[st.top()]=2;
belong[st.top()]=_cnt;
st.pop();
}
sum[_cnt]++;///加的是权值
ins[st.top()]=2;
belong[st.top()]=_cnt;
st.pop();
}
}
ll fa[N];
ll find(ll x)
{
if(fa[x]==x)return x;
return fa[x]=find(fa[x]);
}
void solve()
{
cin>>n>>m;
for(int i=1; i<=m; i++)
{
ll u,v;
string w;
cin>>u>>v>>w;
if(w=="Lun")
{
go[u].pb(v);
go[v].pb(u);
lun.eb(u,v);
}
else
qie.eb(u,v);
};
for(int i=1; i<=n; i++)
{
fa[i]=i;
if(!ins[i])
tanjan(i,0);
}
for(auto [u,v]:lun)
{
if(belong[u]==belong[v])ans.eb(u,v);
}
for(auto [u,v]:qie)
{
if(find(belong[u])!=find(belong[v]))
{
ans.eb(u,v);
fa[find(belong[v])]=find(belong[u]);
_cnt--;
}
}
if(_cnt==1)
{
cout<<"YES\n";
cout<<ans.size()<<'\n';
for(auto [u,v]:ans)
{
cout<<u<<' '<<v<<'\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();
}
}
///在秋天邂逅, 在春天发芽,在夏天壮大,在秋天萧瑟,在冬天萎缩,
///而后,春天再度归来。