12.【2024初三集训模拟测试4】
\(\Huge打了一场模拟赛,又垫底了。qwq\)
2024初三集训模拟测试4
\(\Huge还是垫底赛大佬。qwq\)
- 赛时差点忘改 \(freopen\) ,用的全是 \(T1\) 的文件, \(9:30\) 才发现,吓 \(④\) 。
T1打赌
\(0pts\)
- 又是 \(\Huge\%\) 你 , 打赌 \(\Huge🤬🤬🤬\) \(qwq\) 。
- 本来还能得二三十分,但是 \(CE\) 了。
题解 \(\Huge 🈚\)
代码 \(\Huge 🈚\)
T2舞会
\(20pts\)
- 可以先分别分离想要和比自己高的人跳舞的人和想要和比自己低的人跳舞的人,之后用绝对值排一遍序,然后尽量让身高相差不大的两个人跳舞即可。
题解 \(\Huge 🈶\)
- 无语了,赛时 \(for\) 循环打错了,枚举错了,不然就过了。
- 双指针可以 \(O(n)\) 扫过去。
- 时间复杂度 \(O(n\log n)\) 。
代码 \(\Huge 🈶\)
#include<bits/stdc++.h>
#define int long long
#define N (1000010)
#define I i
#define J j
#define raed read
#define reaD read
#define reAD read
#define rEAD read
#define READ read
#define REAd read
#define REad read
#define Read read
#define Reda read
#define redA read
#define reDA read
#define redA read
#define itn signed
#define Itn signed
#define ITN signed
#define Int signed
#define INT signed
#define foR for
#define fot for
#define foT for
#define sort stable_sort
using namespace std;
namespace IO
{
#define ll long long
const int MAX=1<<24;
char buf[MAX],*p1=buf,*p2=buf;
char obuf[MAX],*o=obuf;
#define gc()(p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<24,stdin),p1==p2)?EOF:*p1++)
//template<typename T>
//inline T read()
inline int read()
{
int x=0;bool f=1;
char c=gc();
for(;c<48||c>57;c=gc())if(c=='-')f=0;
for(;c>=48&&c<=57;c=gc())x=(x<<3)+(x<<1)+(c^48);
return f?x:~x+1;
}
void print(ll x){if(x>9)print(x/10);*o++=(x%10)+'0';}
void pit(ll x){if(x<0)*o++='-',x=~x+1;print(x);}
void write(ll x,char ed){pit(x);*o++=ed;}
void flush(){fwrite(obuf,o-obuf,1,stdout);}
#undef ll
}
using IO::read;using IO::write;using IO::flush;using std::complex;
inline int min(int x,int y){return y&((y-x)>>31)|x&(~(y-x)>>31);}
inline int max(int x,int y){return x&((y-x)>>31)|y&(~(y-x)>>31);}
inline void swap(int &x,int &y){int tmp=x;x=y;y=tmp;}
long long n,m;
void init_set()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
#ifdef ONLINE_JUDGE
freopen("party.in","r",stdin);
freopen("party.out","w",stdout);
#endif
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
}
int tot,t,x,y;
bool cmp(int x,int y){return x>y;}
int furina[100010],fucaros[100010];
int sumeru[100010],nahida[100010];
int fontaine[100010],inazuma[100010];
int l1,l2,l3,l4;
int panzer;
signed main()
{
init_set();
n=read();
for(int i(1);i<=n;++i)furina[i]=read();
for(int i(1);i<=n;++i)fucaros[i]=read();
for(int i(1);i<=n;++i)
{
if(furina[i]<0)sumeru[++l1]=~furina[i]+1;
else nahida[++l2]=furina[i];
if(fucaros[i]<0)fontaine[++l3]=~fucaros[i]+1;
else inazuma[++l4]=fucaros[i];
}
sort(sumeru+1,sumeru+1+l1);
sort(nahida+1,nahida+1+l2);
sort(fontaine+1,fontaine+1+l3);
sort(inazuma+1,inazuma+1+l4);
for(int i(1),j(1);i<=l1&&j<=l4;++i,++j)
{
for(;i<=l1&&sumeru[i]<=inazuma[j];++i);
if(i<=l1&&j<=l4)++panzer;
}
for(int i(1),j(1);i<=l2&&j<=l3;++i,++j)
{
for(;j<=l3&&nahida[i]>=fontaine[j];++j);
if(i<=l2&&j<=l3)++panzer;
}
write(panzer,' ');
flush();
return 0;
}
T3最小生成树
\(100pts\)
- 差点以为又出原题了 \(qwq\) 。
- 本来觉得不可做,但是感觉可以用欧拉函数,虽然不知道对不对 \(qwq\) 。
- 但是确实对了。
题解 \(\Huge 🈶\)
- 我们先将所有不是 \(1\) 的节点与 \(1\) 相连,发现边权都为 \(1\) ,得出结论:只有互质的两个数可以相连。
- 并且给出了除了根节点,其他节点都大于父亲节点。所以不用考虑树的内部情况。
- 因此可以用欧拉函数求出在树中增加 \(i\) 节点时,有多少节点与 \(i\) 互质,每个互质的节点都可以连 \(i\) ,由于 \(i-1\) 的方案数已经求出来,所以相乘即可。 \(\Large ans=\prod\limits_{i=3}^{n}\varphi(i)\) 。
代码 \(\Huge 🈶\)
#include<bits/stdc++.h>
#define int long long
#define N (1000010)
#define I i
#define J j
#define raed read
#define reaD read
#define reAD read
#define rEAD read
#define READ read
#define REAd read
#define REad read
#define Read read
#define Reda read
#define redA read
#define reDA read
#define redA read
#define itn signed
#define Itn signed
#define ITN signed
#define Int signed
#define INT signed
#define foR for
#define fot for
#define foT for
#define sort stable_sort
using namespace std;
namespace IO
{
#define ll long long
const int MAX=1<<24;
char buf[MAX],*p1=buf,*p2=buf;
char obuf[MAX],*o=obuf;
#define gc()(p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<24,stdin),p1==p2)?EOF:*p1++)
//template<typename T>
//inline T read()
inline int read()
{
int x=0;bool f=1;
char c=gc();
for(;c<48||c>57;c=gc())if(c=='-')f=0;
for(;c>=48&&c<=57;c=gc())x=(x<<3)+(x<<1)+(c^48);
return f?x:~x+1;
}
void print(ll x){if(x>9)print(x/10);*o++=(x%10)+'0';}
void pit(ll x){if(x<0)*o++='-',x=~x+1;print(x);}
void write(ll x,char ed){pit(x);*o++=ed;}
void flush(){fwrite(obuf,o-obuf,1,stdout);}
#undef ll
}
using IO::read;using IO::write;using IO::flush;using std::complex;
inline int min(int x,int y){return y&((y-x)>>31)|x&(~(y-x)>>31);}
inline int max(int x,int y){return x&((y-x)>>31)|y&(~(y-x)>>31);}
inline void swap(int &x,int &y){x^=y^=x^=y;}
long long n,m;
void init_set()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
#ifdef ONLINE_JUDGE
freopen("mst.in","r",stdin);
freopen("mst.out","w",stdout);
#endif
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
}
int tot,t,x,y;
int prime[100010],phi[100010],len;
bitset<100010>vis;
void eular(int n)//欧拉筛
{
//memset(vis,0,sizeof(vis));
phi[1]=1;
for(int i(2);i<=n;++i)
{
if(!vis[i])
prime[++len]=i,phi[i]=(i-1);
for(int j(1);j<=len&&i*prime[j]<=n;++j)
{
vis[i*prime[j]]=true;
if(!(i%prime[j]))
{phi[i*prime[j]]=(phi[i]*prime[j]);break;}
else phi[i*prime[j]]=(phi[i]*(prime[j]-1));
}
}
}
int furina[1000010],fucaros[1000010];
int panzer,nahida;
signed main()
{
init_set();
n=read();
eular(n+1);
panzer=1;
for(int i(3);i<=n;++i)
(panzer=panzer*phi[i])%=100000007;
write(panzer,'\n');
flush();
return 0;
}
T4买汽水
\(60pts\)
- 最擅长的一集 \(qwq\Huge🤗🤗🤗\) 。
题解 \(\Huge 🈶\)
-
创新是改革开放的生命,
-
剪枝是 \(dfs\) 的生命。
-
大力 \(dfs\) 干就完了!
-
先剪枝,这题最优性剪枝与可行性剪枝都能用上。
-
最优性剪枝保证不去跑多余的分支,而可行性剪枝在花费过高时及时剪枝,使得复杂度急剧下降。
-
排序后假如 \(\large sum_{\large\frac n2}>m\) 则粗略的判断买汽水的天数少于不买汽水的天数。否则认为不买汽水的天数更多。
-
如果 \(\large sum_{\large\frac n2}>m\) ,则进行 \(dfs(1,0)\) ,否则进行 \(sfd(1,\large sum_n)\) 。
-
关于 \(sfd\) ,就是倒着 \(dfs\) ,先假设每天都买汽水,然后进行排除,这样枚举时搜索到第一个 \(\leq m\) 的花费后即可 \(return\) 。
-
另一道 \(dfs\) ( \(T3\) )。
-
时间复杂度在 \((O(n\log n))\) 到 \(O(2^n)\) 之间,其中 \(n\log n\) 是由于排序。
代码 \(\Huge 🈶\)
#include<bits/stdc++.h>
#define int long long
#define N (1000010)
#define I i
#define J j
#define raed read
#define reaD read
#define reAD read
#define rEAD read
#define READ read
#define REAd read
#define REad read
#define Read read
#define Reda read
#define redA read
#define reDA read
#define redA read
#define itn signed
#define Itn signed
#define ITN signed
#define Int signed
#define INT signed
#define foR for
#define fot for
#define foT for
#define sort stable_sort
using namespace std;
namespace IO
{
#define ll long long
const int MAX=1<<24;
char buf[MAX],*p1=buf,*p2=buf;
char obuf[MAX],*o=obuf;
#define gc()(p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<24,stdin),p1==p2)?EOF:*p1++)
//template<typename T>
//inline T read()
inline int read()
{
int x=0;bool f=1;
char c=gc();
for(;c<48||c>57;c=gc())if(c=='-')f=0;
for(;c>=48&&c<=57;c=gc())x=(x<<3)+(x<<1)+(c^48);
return f?x:~x+1;
}
void print(ll x){if(x>9)print(x/10);*o++=(x%10)+'0';}
void pit(ll x){if(x<0)*o++='-',x=~x+1;print(x);}
void write(ll x,char ed){pit(x);*o++=ed;}
void flush(){fwrite(obuf,o-obuf,1,stdout);}
#undef ll
}
using IO::read;using IO::write;using IO::flush;using std::complex;
inline int min(int x,int y){return y&((y-x)>>31)|x&(~(y-x)>>31);}
inline int max(int x,int y){return x&((y-x)>>31)|y&(~(y-x)>>31);}
inline void swap(int &x,int &y){int tmp=x;x=y;y=tmp;}
long long n,m;
void init_set()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
#ifdef ONLINE_JUDGE
freopen("drink.in","r",stdin);
freopen("drink.out","w",stdout);
#endif
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
}
int tot,t,x,y;
int furina[1000010],fucaros[1000010];
int panzer,nahida;
bool cmp(int x,int y){return x>y;}
void dfs(int x,int sum)
{
//++nahida;
if(panzer==m)write(panzer,' '),flush(),exit(0);
if(x>n){if(sum<=m)panzer=max(panzer,sum);return;}
if(sum+fucaros[n]-fucaros[x-1]<=panzer)return;
//最优性剪枝
if(sum>m)return;//可行性剪枝
if(sum<=m)panzer=max(panzer,sum);//更新答案
dfs(x+1,sum);
if(sum+furina[x]>m)return;//可行性剪枝
dfs(x+1,sum+furina[x]);
}
void sfd(int x,int sum)
{
//++nahida;
if(panzer==m)write(panzer,' '),flush(),exit(0);
if(x>n){if(sum<=m)panzer=max(panzer,sum);return;}
if(sum-fucaros[n]+fucaros[x-1]>m)return;
//这是可行性剪枝。
if(sum<=m){panzer=max(panzer,sum);return;}//最优性
sfd(x+1,sum);
sfd(x+1,sum-furina[x]);
}
signed main()
{
init_set();
n=read();m=read();
for(int i(1);i<=n;++i)furina[i]=read();
sort(furina+1,furina+1+n,cmp);
for(int i(1);i<=n;++i)
fucaros[i]=fucaros[i-1]+furina[i];
if(fucaros[n]<=m)
{
write(fucaros[n],'\n');
flush();exit(0);
}
if(fucaros[n>>1]>=m)dfs(1,0);
else sfd(1,fucaros[n]);
//write(nahida,' ');
write(panzer,' ');
flush();
return 0;
}
\(\Huge打了一场模拟赛,又垫底了。qwq\)