11.27 noip模拟赛
信心赛,又双叒叕挂分了……
T1
打表,未果,寻洪文,后遂无问津者
然后很唐的对着错误的大样例调了半天
后来小 L 从我身后经过,说:“这大样例是假的,你再说,假吗”
发现如果当前钱数 \(>ax\) 那么买 \(a\) 瓶又获得 \(b\) 元等价于花费 \(ax-b\)
然后就可以 \(O(1)\) 求出买几个 \(ax\) 捆绑套餐,然后剩的钱单独算一下即可
赛后发现挂分了
因为我写的是向上取整,但是正解是向下取整再加一
因为你剩的钱完全够再买一次,所以 \(100 \rightarrow 40\)
点击查看代码
#include<bits/stdc++.h>
#define int long long
#define ll long long
#define fd(i,a,b) for(int i=(a);i<=(b);i=-~i)
#define bd(i,a,b) for(int i=(a);i>=(b);i=~-i)
#define db(x) cout<<"DEBUG "<<#x<<" = "<<x<<endl;
#define endl '\n'
using namespace std;
template<typename _T=int>
inline _T read()
{
_T x=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-') f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=x*10+(c-48);c=getchar();}
return x*f;
}
template<typename _T>
inline void write(_T x)
{
static _T sta[35];int top=0;
if(x<0) putchar('-'),x=-x;
do{sta[top++]=x%10,x/=10;}while(x);
while(top) putchar(sta[--top]+'0');
}
const int N=1e6+509,M=1e6+509,mod=998244353;
int n,a,b,v;
void Main()
{
n=read(),v=read(),a=read(),b=read();
if(n>=v*a&&b>=v*a)
{
printf("-1\n");
return;
}
if(n<v*a||b==0)
{
printf("%lld\n",n/v);
}
else
{
int del=v*a-b;
int k=(n-v*a)/del+1;
int ans=k*a+(n-k*del)/v;
printf("%lld\n",ans);
}
}
signed main()
{
#define FJ
#ifdef FJ
freopen("buy.in","r",stdin);
freopen("buy.out","w",stdout);
#else
freopen("buy2.in","r",stdin);
freopen("buy.out","w",stdout);
#endif
int T=read();
while(T--) Main();
return 0;
}
T2
很唐啊,我判的是这个点能否当重叠点,但是是假的
因为转移的时候可能那个块挤不过去,然后就被 HACK 了,而且还有可恶的 \(\text{Subtask}\)
正解其实跟我差不多,就是能转移的话把点入队,跑 BFS 即可
(但是你这题为什么要先读 \(m\) 再读 \(n\),先读 \(y\) 再读 \(x\),还有这个图片纯误导人,\(k1\),\(k2\) 读反都能过)
然鹅我的假算法在 \(\text{Subtask}\) 的情况下还有 \(27\) 分
点击查看代码
#include<bits/stdc++.h>
#define int long long
#define ll long long
#define fd(i,a,b) for(int i=(a);i<=(b);i=-~i)
#define bd(i,a,b) for(int i=(a);i>=(b);i=~-i)
#define db(x) cout<<"DEBUG "<<#x<<" = "<<x<<endl;
#define endl '\n'
using namespace std;
template<typename _T=int>
inline _T read()
{
_T x=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-') f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=x*10+(c-48);c=getchar();}
return x*f;
}
template<typename _T>
inline void write(_T x)
{
static _T sta[35];int top=0;
if(x<0) putchar('-'),x=-x;
do{sta[top++]=x%10,x/=10;}while(x);
while(top) putchar(sta[--top]+'0');
}
const int N=1e3+5e2+509,M=1e6+509,mod=998244353;
bool vis[N][N];
int u[N][N],d[N][N],l[N][N],r[N][N];
int h,w,k1,k2;
char mp[N][N];
int stx,sty,edx,edy;
struct node{int x,y;};
inline bool operator<(node xx,node yy)
{
return abs(edx-xx.x)+abs(edy-xx.y)>abs(edx-yy.x)+abs(edy-yy.y);
}
int dx[]={0,0,0,1,-1},dy[]={0,1,-1,0,0};
priority_queue<node> q;
signed main()
{
#define FJ
#ifdef FJ
freopen("puzzle.in","r",stdin);
freopen("puzzle.out","w",stdout);
#else
// freopen("puzzle3.in","r",stdin);
// freopen("puzzle.out","w",stdout);
#endif
w=read(),h=read(),k1=read(),k2=read();
read();
stx=read()+1;
sty=read()+1;
read();
fd(i,1,h)
{
fd(j,1,w)
{
cin>>mp[i][j];
if(mp[i][j]=='*') edx=i,edy=j;
}
}
fd(i,1,h)
{
int L=1,R=1;
while(R<=w)
{
while(mp[i][L]=='X'&&L<=w) ++L;
if(L>w) break;
R=L;
while(mp[i][R+1]!='X'&&R<w) ++R;
fd(j,L,R) l[i][j]=L,r[i][j]=R;
L=R+1;
if(L>w) break;
}
}
fd(i,1,w)
{
int L=1,R=1;
while(R<=h)
{
while(mp[L][i]=='X'&&L<=h) ++L;
if(L>h) break;
R=L;
while(mp[R+1][i]!='X'&&R<h) ++R;
fd(j,L,R) u[j][i]=L,d[j][i]=R;
L=R+1;
if(L>h) break;
}
}
// fd(x,1,h)
// fd(y,1,w)
// {
// cerr<<x<<' '<<y<<endl;
// cerr<<u[x][y]<<' '<<d[x][y]<<endl;
// cerr<<l[x][y]<<' '<<r[x][y]<<endl;
// cerr<<endl;
// }
q.push({stx,sty});
while(!q.empty())
{
int x=q.top().x,y=q.top().y;q.pop();
// cerr<<x<<' '<<y<<endl;
// cerr<<u[x][y]<<' '<<d[x][y]<<endl;
// cerr<<l[x][y]<<' '<<r[x][y]<<endl;
vis[x][y]=1;
if(x==edx&&y==edy)
{
cout<<"YES";
return 0;
}
fd(i,1,4)
{
int nx=x+dx[i],ny=y+dy[i];
if(nx<1||ny<1||nx>h||ny>w||vis[nx][ny]||mp[nx][ny]=='X') continue;
if(min(r[x][y],r[nx][ny])-max(l[x][y],l[nx][ny])+1<k1)
{
// cerr<<"#1 "<<r[nx][ny]<<' '<<l[nx][ny]<<' '<<min(r[x][y],r[nx][ny])-max(l[x][y],l[nx][ny])+1<<endl;
continue;
}
if(min(d[x][y],d[nx][ny])-max(u[x][y],u[nx][ny])+1<k2)
{
// cerr<<"#2 "<<u[nx][ny]<<' '<<d[nx][ny]<<' '<<min(d[x][y],d[nx][ny])-max(u[x][y],u[nx][ny])+1<<endl;
continue;
}
vis[nx][ny]=1,q.push({nx,ny});
}
}
cout<<"NO";
return 0;
}
T3
发现保留最短路上的点最优
但是我根本没想到什么最小生成树枚举树根
我想的是保留的一定是重叠的,并且都在根节点到 \(s1,s2\) 最短路上的一部分共同边再加上向 \(s1\) 和 \(s2\) 的分叉
然后我跑 DFS,居然过了,而且跑得飞快,我甚至没加记忆化(
正解是枚举树根,算到 \(1,s1,s2\) 三点的距离和并取 \(\min\)
点击查看代码
#include<bits/stdc++.h>
#define int long long
#define ll long long
#define fd(i,a,b) for(int i=(a);i<=(b);i=-~i)
#define bd(i,a,b) for(int i=(a);i>=(b);i=~-i)
#define db(x) cout<<"DEBUG "<<#x<<" = "<<x<<endl;
#define endl '\n'
using namespace std;
template<typename _T=int>
inline _T read()
{
_T x=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-') f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=x*10+(c-48);c=getchar();}
return x*f;
}
template<typename _T>
inline void write(_T x)
{
static _T sta[35];int top=0;
if(x<0) putchar('-'),x=-x;
do{sta[top++]=x%10,x/=10;}while(x);
while(top) putchar(sta[--top]+'0');
}
const int N=3e3+509,M=1e6+509,mod=998244353;
int n,m,s1,s2,t1,t2;
vector<int> e[N];
int d[3][N],vis[N];
priority_queue< pair<int,int> > q;
int ans,mx;
void dij(int op)
{
memset(d[op],0x3f,sizeof(d[op]));
memset(vis,0,sizeof(vis));
int s;
if(op==0) s=1;
if(op==1) s=s1;
if(op==2) s=s2;
d[op][s]=0;
q.push({0,s});
while(!q.empty())
{
int x=q.top().second;q.pop();
if(vis[x]) continue;
vis[x]=1;
for(auto &y:e[x])
{
if(d[op][y]>d[op][x]+1)
{
d[op][y]=d[op][x]+1;
q.push({-d[op][y],y});
}
}
}
}
void dfs(int x,int len,int fa)
{
mx=max(mx,len);
for(auto &y:e[x])
{
if(y==fa) continue;
if(d[0][x]+1+d[1][y]==d[0][s1]&&d[0][x]+1+d[2][y]==d[0][s2])
{
dfs(y,len+1,x);
}
}
}
signed main()
{
#define FJ
#ifdef FJ
freopen("boom.in","r",stdin);
freopen("boom.out","w",stdout);
#else
freopen("boom3.in","r",stdin);
freopen("boom.out","w",stdout);
#endif
n=read(),m=read();
fd(i,1,m)
{
int x=read(),y=read();
e[x].push_back(y);
e[y].push_back(x);
}
s1=read(),t1=read(),s2=read(),t2=read();
dij(0),dij(1),dij(2);
if(d[0][s1]>t1||d[0][s2]>t2)
{
puts("-1");
return 0;
}
ans=d[0][s1]+d[0][s2];
dfs(1,0,0);
printf("%lld",m-(ans-mx));
return 0;
}
T4
DP 题,但是赛时写的 \(O(n m^n)\) 的暴力 T 了
然后记 \(f_{i,j,k,l}\) 表示前 \(i\) 位,确定了 \(j\) 个数,有 \(k\) 个 \(1\),向后的进位是 \(l\) 的总和
然后转移是枚举 \(a_j=i\) 的个数,令其为 \(t\)
那么可以转移:
然后就做完了
点击查看代码
#include<bits/stdc++.h>
#define int long long
#define ll long long
#define fd(i,a,b) for(int i=(a);i<=(b);i=-~i)
#define bd(i,a,b) for(int i=(a);i>=(b);i=~-i)
#define db(x) cout<<"DEBUG "<<#x<<" = "<<x<<endl;
#define endl '\n'
using namespace std;
template<typename _T=int>
inline _T read()
{
_T x=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-') f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=x*10+(c-48);c=getchar();}
return x*f;
}
template<typename _T>
inline void write(_T x)
{
static _T sta[35];int top=0;
if(x<0) putchar('-'),x=-x;
do{sta[top++]=x%10,x/=10;}while(x);
while(top) putchar(sta[--top]+'0');
}
const int N=35,M=109,mod=998244353;
int n,m,K;
int f[M][N][N][N],v[M],c[N][N];
inline int qpow(int x,int y)
{
int re=1;
while(y)
{
if(y&1) (re*=x)%=mod;
(x*=x)%=mod,y>>=1;
}
return re;
}
inline int popcont(int x)
{
int cnt=0;
while(x) ++cnt,x-=x&-x;
return cnt;
}
signed main()
{
#define FJ
#ifdef FJ
freopen("count.in","r",stdin);
freopen("count.out","w",stdout);
#else
// freopen("count2.in","r",stdin);
// freopen("count.out","w",stdout);
#endif
n=read(),m=read(),K=read();
fd(i,0,m) v[i]=read();
c[0][0] = 1;
fd(i,1,31)
{
c[i][0]=1;
fd(j,1,i) c[i][j]=(c[i-1][j]+c[i-1][j-1])%mod;
}
f[0][0][0][0]=1;
fd(i,1,n) f[0][i][i&1][i/2]=c[n][i]*qpow(v[0],i)%mod;
fd(i,0,m-1) fd(j,0,n) fd(k,0,K) fd(p,0,n/2) fd(q,0,n-j)
if(f[i][j][k][p]) (f[i+1][q+j][k+((p+q)&1)][(p+q)/2]+=(f[i][j][k][p]*qpow(v[i+1],q)%mod*c[n-j][q]%mod))%=mod;
int ans=0;
fd(k,0,K) fd(p,0,n/2)
if(k+popcont(p)<=K) (ans+=f[m][n][k][p])%=mod;
printf("%lld",ans);
return 0;
}
本文来自博客园,作者:whrwlx,转载请注明原文链接:https://www.cnblogs.com/whrwlx/p/18573192
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 实操Deepseek接入个人知识库
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· 【.NET】调用本地 Deepseek 模型
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库