2022.7.14 模拟赛
2022.7.14 模拟赛#
数独#
思路:
大模拟
写完调完,难度一般般
#include<bits/stdc++.h>
using namespace std;
inline int read(){
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}
while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*f;
}
char a[20][20];
int s[10][10];
int t[101][10][10];
inline void check_1(int x,int y,int k){
for(int i=1;i<=9;++i)
if(s[x][i]==k){puts("Error:row!");return;}
for(int i=1;i<=9;++i)
if(s[i][y]==k){puts("Error:column!");return;}
int a=(x-1)/3*3+1,b=(y-1)/3*3+1;
for(int i=a;i<=a+2;++i)
for(int j=b;j<=b+2;++j)
if(s[i][j]==k){puts("Error:square!");return;}
s[x][y]=k;
puts("OK!");
return;
}
inline void check_2(int x,int y){
bool vis[10]={0};
int cnt=0;
for(int i=1;i<=9;++i) vis[s[x][i]]=vis[s[i][y]]=1;
int a=(x-1)/3*3+1,b=(y-1)/3*3+1;
for(int i=a;i<=a+2;++i)
for(int j=b;j<=b+2;++j)
vis[s[i][j]]=1;
for(int i=1;i<=9;++i) if(!vis[i]) ++cnt;
cout<<cnt<<endl;
for(int i=1;i<=9;++i) if(!vis[i]) cout<<i<<endl;
return;
}
bool l[10][10],c[10][10],u[10][10];
inline void comb(int x,int y){
memset(l,0,sizeof(l));
memset(c,0,sizeof(c));
memset(u,0,sizeof(u));
memset(s,0,sizeof(s));
int cnt1=0,cnt2=0;
for(int i=1;i<=9;++i)
for(int j=1;j<=9;++j){
int a=t[x][i][j],b=t[y][i][j];
if(a&&!s[i][j]&&!l[i][a]&&!c[j][a]&&!u[(i-1)/3*3+(j-1)/3+1][a]){
l[i][a]=c[j][a]=u[(i-1)/3*3+(j-1)/3+1][a]=1;
++cnt1;s[i][j]=a;
}
else if(b&&!s[i][j]&&!l[i][b]&&!c[j][b]&&!u[(i-1)/3*3+(j-1)/3+1][b]){
l[i][b]=c[j][b]=u[(i-1)/3*3+(j-1)/3+1][b]=1;
++cnt2;s[i][j]=b;
}
}
cout<<cnt1<<" "<<cnt2<<endl;
}
signed main(){
for(int i=1;i<=19;++i)
for(int j=1;j<=19;++j){
cin>>a[i][j];
if(i%2==1||j%2==1) continue;
s[i/2][j/2]=a[i][j]-'0';
}
int T=read();
for(int q=1;q<=T;++q){
string A;
cin>>A;
int x,y,k;
if(A[0]=='I'){
x=read(),y=read(),k=read();
if(s[x][y]) puts("Error!");
else check_1(x,y,k);
}
if(A[0]=='D'){
x=read(),y=read();
if(!s[x][y]) puts("Error!");
else{s[x][y]=0;puts("OK!");}
}
if(A[0]=='Q'){
x=read(),y=read();
if(s[x][y]) puts("Error!");
else check_2(x,y);
}
if(A[0]=='M'){x=read(),y=read();comb(x,y);}
if(A[0]=='P'){
for(int i=1;i<=19;++i){
for(int j=1;j<=19;++j){
if(isdigit(a[i][j])) cout<<s[i/2][j/2];
else cout<<a[i][j];
}
cout<<endl;
}
}
memcpy(t[q],s,sizeof(s));
}
}
分糖果#
思路:
看到这个式子:
看到
显然不能 ,显然可以贪心
直接分析 和
那么如果 在 前,则有
排序+贪心即可
此题做完了
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5;
#define ll long long
#define int long long
inline int read(){
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}
while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*f;
}
int n;
struct man{
int a,b;
inline bool operator < (const man X) const{
return a+X.b+max(b,X.a)<X.a+b+max(X.b,a);
}
}d[N];
ll s[N],c[N];
signed main(){
int T=read();
while(T--){
n=read();
for(int i=1;i<=n;++i)
d[i].a=read(),d[i].b=read();
sort(d+1,d+n+1);
c[1]=d[1].a+d[1].b;
for(int i=1;i<=n;++i) s[i]=s[i-1]+1ll*d[i].a;
for(int i=2;i<=n;++i){
c[i]=max(c[i-1],s[i])+1ll*d[i].b;
}
printf("%lld\n",c[n]);
}
}
维修机器人#
思路:
不同的 最多 个,
计算一下,,可以直接离散化,上 的
下面只阐述单调不下降的 方法,单调不上升同理
设 表示保证前 个有序的情况下最后一个数为 , 表示
那么可以得到:
做完了
#include<bits/stdc++.h>
using namespace std;
const int N=5e4+1;
#define re register
inline int read(){
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}
while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*f;
}
int n,m1,m2;
int a[N];
namespace qaq{
int f[N][1002],g[1002];
int b[N],c[N],cnt;
int ans=1e9;
inline void lsh(){
memcpy(b,a,sizeof(a));
sort(b+1,b+n+1);
c[++cnt]=b[1];
for(re int i=2;i<=n;++i)
if(b[i]!=b[i-1]) c[++cnt]=b[i];
for(re int i=1;i<=n;++i)
a[i]=lower_bound(c+1,c+cnt+1,a[i])-c;
}
inline void pre1(){
memset(f,0x3f,sizeof(f));
memset(g,0x3f,sizeof(g));
f[1][a[1]]=0;
for(re int i=a[1]-1;i;--i) f[1][i]=m2;
for(re int i=a[1]+1;i<=cnt;++i) f[1][i]=m1;
g[1]=f[1][1];
for(re int i=2;i<=cnt;++i) g[i]=min(g[i-1],f[1][i]);
}
inline void pre2(){
memset(f,0x3f,sizeof(f));
memset(g,0x3f,sizeof(g));
f[1][a[1]]=0;
for(re int i=a[1]-1;i;--i) f[1][i]=m2;
for(re int i=a[1]+1;i<=cnt;++i) f[1][i]=m1;
g[cnt]=f[1][cnt];
for(re int i=cnt-1;i;++i) g[i]=min(g[i+1],f[1][i]);
}
inline void dp(){
pre1();
for(re int i=2;i<=n;++i){
for(re int j=1;j<=cnt;++j)
f[i][j]=g[j];
for(re int j=1;j<=cnt;++j){
if(j>a[i]) f[i][j]+=m1;
if(j<a[i]) f[i][j]+=m2;
}
memset(g,0x3f,sizeof(g));
g[1]=f[i][1];
for(re int j=1;j<=cnt;++j)
g[j]=min(f[i][j],g[j-1]);
}
for(re int i=1;i<=cnt;++i) ans=min(ans,f[n][i]);
}
inline void solve(){
lsh();
dp();
reverse(a+1,a+n+1);
dp();
cout<<ans<<endl;
}
}
signed main(){
n=read(),m1=read(),m2=read();
for(int i=1;i<=n;++i){
a[i]=read();
}
qaq::solve();
}
小乔#
思路:
最终的答案应该等于
首先的想法是按照半径从大到小枚举,因为每个地方最多只会被覆盖一次,我们就找到能将当前点覆盖的第 次是什么时候,这时就是该点所求的值
因此我们需要边修改 (区间加) 边查询 (区间第一次大于等于 的数字个数) 并且将已经统计过的点打标记
看到 这不分块吗?
考虑用分块维护上述操作
时间复杂度 (因为点是从 编号)
注意细节:题目中 可能大于 ,此时需要分段统计
,这题细节真滴多,考场上没看到 可能大于 只拿了
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
#define int long long
inline int read(){
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}
while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*f;
}
int n,m,k,q,sz;
int tag[500],v[N*2],bl[N*2],L[500],R[500],mn[500];
bool vis[N*2];
int cnt[500][N];
long long ans;
struct opt{
int r,s,t;
inline bool operator < (const opt x){
return r>x.r;
}
}a[N];
inline void solve(int x,int y,int val){
if(y<x) return;
int l=bl[x],r=bl[y];
if(l==r){
for(int i=x;i<=y;++i){
if(vis[i]||(mn[l]!=-1&&v[i]>=mn[l])) continue;
--cnt[l][v[i]];
++v[i];
if(v[i]+tag[l]>=k){
vis[i]=1;
ans+=1ll*val*1ll*val;
continue;
}
++cnt[l][v[i]];
}
if(cnt[l][k-tag[l]]){
ans+=1ll*cnt[l][k-tag[l]]*1ll*val*1ll*val;
cnt[l][k-tag[l]]=0;
mn[l]=min(mn[l],k-tag[l]);
}
return;
}
for(int i=x;i<=R[l];++i){
if(vis[i]||(mn[l]>=0&&v[i]>=mn[l])) continue;
--cnt[l][v[i]];
++v[i];
if(v[i]+tag[l]>=k){
vis[i]=1;
ans+=1ll*val*val;
continue;
}
++cnt[l][v[i]];
}
for(int i=L[r];i<=y;++i){
if(vis[i]||(mn[r]>=0&&v[i]>=mn[r])) continue;
--cnt[r][v[i]];
++v[i];
if(v[i]+tag[r]>=k){
vis[i]=1;
ans+=1ll*val*1ll*val;
continue;
}
++cnt[r][v[i]];
}
if(cnt[l][k-tag[l]]){
ans+=1ll*cnt[l][k-tag[l]]*1ll*val*1ll*val;
cnt[l][k-tag[l]]=0;
mn[l]=min(mn[l],k-tag[l]);
}
if(cnt[r][k-tag[r]]){
ans+=1ll*cnt[r][k-tag[r]]*1ll*val*1ll*val;
cnt[r][k-tag[r]]=0;
mn[r]=min(mn[r],k-tag[r]);
}
for(int i=l+1;i<=r-1;++i){
++tag[i];
if(cnt[i][k-tag[i]]){
ans+=1ll*cnt[i][k-tag[i]]*1ll*val*1ll*val;
cnt[i][k-tag[i]]=0;
mn[i]=min(mn[i],k-tag[i]);
}
}
}
signed main(){
n=read(),m=read(),k=read();
memset(mn,0x3f,sizeof(mn));
for(int i=1;i<=n;++i){
a[i].r=read(),a[i].s=read(),a[i].t=read();
}
q=m;
m=m*2;
sz=sqrt(m);
for(int i=1;i<=m;++i){
bl[i]=(i-1)/sz+1;
++cnt[bl[i]][0];
if(bl[i]!=bl[i-1]) L[bl[i]]=i,R[bl[i-1]]=i-1;
}
R[bl[m]]=m;
sort(a+1,a+n+1);
for(int i=1;i<=n;++i){
if(a[i].s>a[i].t){
solve(a[i].s+q+1,m,a[i].r);
solve(1,a[i].t+q,a[i].r);
}
else solve(a[i].s+q+1,a[i].t+q,a[i].r);
}
printf("%lld",ans);
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现
2020-07-14 逆序对
2020-07-14 分治学习笔记