今天干了三道--7.19
1.Silly Sort
- 题意:每次操作可以交换两点,但代价为两点的数字和,使得数列有序。
- 思路:在网络上搜到了一个置换组的名词,之前听nodgd也说过。置换组具有独立的性质,每个置换组单独处理,具体:
1.用其中最小的点去一次交换每个点
2.用整个数列最小的点换置换组中最小的点,然后按1,最后换回.
可以证明没有比1,2两种情况更优的! - 代码:
#include<stdio.h>
#include<bits/stdc++.h>
using namespace std;
const int N=1e3+5;
int a[N],val[N],p[N],n,inf=0x3f3f3f3f;
int main() {
int t=0;
while(1) {
t++;
int mn=inf,ans=0;
scanf("%d",&n);
if(!n) break;
for(int i=1;i<=n;i++) scanf("%d",&a[i]),val[i]=a[i],mn=min(a[i],mn);
sort(val+1,val+1+n);
for(int i=1;i<=n;i++) p[a[i]]=i;
for(int i=1;i<=n;i++) {
int mn2=inf,x=i,sum=0,cnt=0;
while(a[x]!=-1&&a[x]!=val[x]) {
mn2=min(mn2,a[x]);
sum+=a[x];
a[x]=-1;
x=p[val[x]];
cnt++;
}
if(mn2==inf) continue;
sum-=mn2; //sum里面包括了mn2
ans+=min((cnt-1)*mn2+sum,(cnt+1)*mn+sum+mn2*2);
}
printf("Case %d: %d\n",t,ans);
puts("");
}
return 0;
}
2.Block Compaction
- 题意:有很多个长方块【方块之间顶多刚好面重合,不可相交】,循环操作(直到两种操作都无法进行):1.将所有长方块尽量往下靠,2.将所有长方块尽量往左靠。
- 思路:对于1操作,我们按上位置排序,然后用前面的与其有概率下落后重叠的块的上表面的最大值更新下表面下降的位置,如果下面没有直接沉底
对于2操作,我们按右位置排序,然后同理。 - 代码:
#include<stdio.h>
#include<bits/stdc++.h>
using namespace std;
const int N=1e3+5;
struct node {
int w,h,u,d,l,r;
}a[N];
bool cmp1(node a,node b) {
return a.u<b.u;
}
bool cmp2(node a,node b) {
return a.r<b.r;
}
int main() {
int n,T;
scanf("%d",&T);
while(T--) {
scanf("%d",&n);
for(int i=1;i<=n;i++) {
int x,y,p,q;
scanf("%d%d%d%d",&x,&y,&p,&q);
a[i]=(node){p-x,q-y,q,y,x,p};
}
bool flag;
do {
//1
flag=false;
sort(a+1,a+1+n,cmp1);
for(int i=1;i<=n;i++) {
int mx=-1;
for(int j=1;j<i;j++) {
if(a[j].l>=a[i].r||a[j].r<=a[i].l) continue;
mx=max(mx,a[j].u); //在底下的上高最高的长方体
}
if(mx==-1) {
if(a[i].d)flag=true;
a[i].d=0,a[i].u=a[i].h;
}
else if(a[i].d>mx){
a[i].d=mx,a[i].u=mx+a[i].h;flag=true;
}
}
//2
sort(a+1,a+1+n,cmp2);
for(int i=1;i<=n;i++) {
int mx=-1;
for(int j=1;j<i;j++) {
if(a[j].u<=a[i].d||a[j].d>=a[i].u) continue;
mx=max(mx,a[j].r);
}
if(mx==-1) {
if(a[i].l) flag=true;
a[i].l=0,a[i].r=a[i].w;
}
else if(a[i].l>mx) {
a[i].l=mx,a[i].r=mx+a[i].w;flag=true;
}
}
// for(int i=1;i<=n;i++) {
// printf("(%d:) l=%d r=%d u=%d d=%d\n",i,a[i].l,a[i].r,a[i].u,a[i].d);
// }
// }
}while(flag);
int ansh=0,answ=0;
for(int i=1;i<=n;i++) {
ansh=max(ansh,a[i].u),answ=max(answ,a[i].r);
}
printf("%d %d\n",answ,ansh);
}
return 0;
}
3.Vasya and a Tree
- 题意:一棵树,q个操作,每个将x的子树中距离它不超过d的点更新。
- 思路:我一开始英文不好把不超过看成了等于,发现能用明显的dfs序做。
然后正解其实很巧妙,利用dfs的顺序,我们把操作用结构体+vector存在点里面,然后dfs存一个sum遇到新点就sum+val,而且打一个标记使得d层之后将sum-val,但注意的是回溯的时候要清空标记。 - 代码:
#include<stdio.h>
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5;
typedef long long ll;
ll Lazy[N],a[N];
int m,nxt[N],dep[N],to[N],head[N],ecnt,n;
struct node {
int D;ll val;
};
vector<node> V[N];
void add_edge(int u,int v) {nxt[++ecnt]=head[u];to[ecnt]=v;head[u]=ecnt;}
void dfs(int u,int fa,ll sum) {
dep[u]=dep[fa]+1;
sum-=Lazy[dep[u]];
for(int i=0;i<V[u].size();i++) {
int Ad=V[u][i].D,v=V[u][i].val;
Lazy[min(dep[u]+Ad,n)+1]+=v,sum+=v;
}
a[u]=sum;
for(int i=head[u];i;i=nxt[i]) {
int v=to[i];
if(v==fa)continue;
dfs(v,u,sum);
}
for(int i=0;i<V[u].size();i++) {
int Ad=V[u][i].D,v=V[u][i].val;
Lazy[min(dep[u]+Ad,n)+1]-=v;
}
}
int main() {
scanf("%d",&n);
for(int i=1;i<n;i++) {
int u,v;
scanf("%d%d",&u,&v);
add_edge(u,v),add_edge(v,u);
}
scanf("%d",&m);
for(int i=1;i<=m;i++) {
int x,d,v;
scanf("%d%d%d",&x,&d,&v);
V[x].push_back(node{d,v});
}
dfs(1,0,0);
for(int i=1;i<=n;i++) printf("%lld ",a[i]);
return 0;
}
4.Regular Number
- 题意:字符串匹配问题,模式串每一位可能有多种填法。
- 思路:shift&算法。
下列变量用bitset维护
用c[i]表示i的值可以在模式串哪些位出现的状态,dp第i位表示当前有连续i位能匹配上,每新加的0位为1因为只有一位的情况可以直接放入。 - 代码:
#include<bits/stdc++.h>
using namespace std;
const int N=1e3+5;
const int M=5e6+5;
bitset<N>c[N],dp;
char s[M];
string ans;
int main() {
int n;
scanf("%d",&n);
for(int i=0;i<n;i++) {
int x,cc;
scanf("%d",&cc);
for(int j=1;j<=cc;j++) {
scanf("%d",&x);
c[x][i]=1;
}
}
scanf("%s",s);
for(int i=0,sz=strlen(s);i<sz;i++) {
(dp<<=1)[0]=1;
dp&=c[s[i]-'0'];
if(dp[n-1]) {
for(int j=i-n+1;j<=i;j++) {
ans+=s[j];
}
ans+='\n';
}
}
printf("%s",ans.c_str());
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人