12.【2024初三集训模拟测试4】

qwq

2024初三集训模拟测试4

qwq

  • 赛时差点忘改 freopen ,用的全是 T1 的文件, 9:30 才发现,吓

T1打赌

0pts

  • 又是 % 你 , 打赌 🤬🤬🤬 qwq
  • 本来还能得二三十分,但是 CE 了。

题解 🈚

代码 🈚

T2舞会

20pts

  • 可以先分别分离想要和比自己高的人跳舞的人和想要和比自己低的人跳舞的人,之后用绝对值排一遍序,然后尽量让身高相差不大的两个人跳舞即可。

题解 🈶

  • 无语了,赛时 for 循环打错了,枚举错了,不然就过了。
  • 双指针可以 O(n) 扫过去。
  • 时间复杂度 O(nlogn)

代码 🈶

#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
  • 但是确实对了。

题解 🈶

  • 我们先将所有不是 1 的节点与 1 相连,发现边权都为 1 ,得出结论:只有互质的两个数可以相连。
  • 并且给出了除了根节点,其他节点都大于父亲节点。所以不用考虑树的内部情况。
  • 因此可以用欧拉函数求出在树中增加 i 节点时,有多少节点与 i 互质,每个互质的节点都可以连 i ,由于 i1 的方案数已经求出来,所以相乘即可。 ans=i=3nφ(i)

代码 🈶

#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🤗🤗🤗

题解 🈶

  • 创新是改革开放的生命,

  • 剪枝是 dfs 的生命。

  • 大力 dfs 干就完了!

  • 先剪枝,这题最优性剪枝与可行性剪枝都能用上。

  • 最优性剪枝保证不去跑多余的分支,而可行性剪枝在花费过高时及时剪枝,使得复杂度急剧下降。

  • 排序后假如 sumn2>m 则粗略的判断买汽水的天数少于不买汽水的天数。否则认为不买汽水的天数更多。

  • 如果 sumn2>m ,则进行 dfs(1,0) ,否则进行 sfd(1,sumn)

  • 关于 sfd ,就是倒着 dfs ,先假设每天都买汽水,然后进行排除,这样枚举时搜索到第一个 m 的花费后即可 return

  • 另一道 dfs T3 )。

  • 时间复杂度在 (O(nlogn))O(2n) 之间,其中 nlogn 是由于排序。

代码 🈶

#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;
}

qwq

posted @   minecraft114514  阅读(27)  评论(1编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示