赛时解决题目: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();
}
}
///在秋天邂逅, 在春天发芽,在夏天壮大,在秋天萧瑟,在冬天萎缩,
///而后,春天再度归来。