文章目录

  • 1001题
    • Bragging Dice
      • 题目大意
      • 思路
      • 代码
  • 1007题
    • Darnassus
      • 题目大意
      • 思路
      • 代码
  • 1008题
    • Orgrimmar
      • 题目大意
      • 思路
      • 代码
  • 1011题
    • Stormwind
      • 题目大意
      • 思路
      • 代码

1001题

Bragging Dice

题目链接

题目大意

给一个只含01的字符串s,可以对任意的奇数长度区间翻转,可操作任意次数,输出s能变成的字典序最小的字符串。

思路

奇数长度翻转,意味着翻转后不改变奇偶性
所以每个 111 可以移动到任意同奇偶的位置
贪心地把 111 移到右边即可
具体看一组样例操作吧

发现答案由三部分组成,第一部分全是 000,第二部分 010101 交替,第三部分全是 111
我们分别统计在奇数位置和偶数位置上 111 的数量
然后按规律排列即可

代码

#include<bits/stdc++.h>
using namespace std;
string s;
void solve()
{int ji=0,ou=0;s="";cin>>s;int len=s.length();for(int i=0;i<len;i++){if(s[i]=='1')    i&1 ? ou++ : ji++;}int minn=min(ji,ou);ji-=minn,ou-=minn;int tmp=len-minn*2-ji*2-ou*2;for(int i=1;i<=tmp;i++) printf("0");if(len&1) //奇后偶前{if(ji) for(int i=1;i<=ji;i++) printf("01");if(ou) for(int i=1;i<=ou;i++) printf("10");}else //奇前偶后{if(ji) for(int i=1;i<=ji;i++) printf("10");if(ou) for(int i=1;i<=ou;i++) printf("01");}for(int i=1;i<=minn;i++) printf("11");cout<<endl;
}
int main()
{int test;cin>>test; while(test--){solve();}
}

1007题

Darnassus

原题链接

题目大意

给你点的数量 n(n⩽50000)n(n \leqslant 50000)n(n⩽50000)和一个 1∼n1 \sim n1∼n 的排列p。点的标号从 111 到 nnn,点 iii 在排列 ppp 中对应的值为 p[i]p[i]p[i],任意两点间的边权为 ∣i−j∣×∣p[i]−p[j]∣|i − j|×|p[i] − p[j]|∣i−j∣×∣p[i]−p[j]∣ ,求最小生成树。

思路

​ nnn 的数量看起来不大,但边的数量是 n2n^2n2,prim和kruskal都不好处理,但也就边的数量过多这一个问题了,所以考虑删除一些不太可能成为树边的边。

​ 观察可得点标号 iii 和排列中对应值 p[i]p[i]p[i] (以下简称为值)一一对应且计算边权时完全等价,将式子中差的绝对值视为距离,则可以很容易地发现距离越近则边权往往越小。由于 iii 和 p[i]p[i]p[i] 等价,所以需要同时考虑点在标号中的距离和在排列中的距离,选择距离较近的一些边跑最小生成树算法

​ 到这一步,问题已经可解,唯一没有确定的是“距离较近的边”具体有多近。不考虑证明的话,直接在可容许的时间复杂度内选择尽量远的边即可,推荐试一试常见数,比如 log2(n)log2(n)log2(n)、sqrt(n)sqrt(n)sqrt(n) 等等。由于生成树时每个点都要走一遍,所以基础复杂度就O(n)O(n)O(n)了,显然也没有多少数可以选择。别整成 n2n^2n2 就行

​ 正解是 sqrt(n)sqrt(n)sqrt(n)。

​ 因为我们可以令标号差或值差尽可能地小——也就是 111,然后另外一个顶天了也就是 n−1n-1n−1 ,所以最小生成树的边权不会大于等于 nnn 。还记得边权的公式吗?现在是 ∣i−j∣×∣p[i]−p[j]∣<n|i − j|×|p[i] − p[j]| < n∣i−j∣×∣p[i]−p[j]∣<n,显然只需要分别枚举 ∣i−j∣|i − j|∣i−j∣ 和 ∣p[i]−p[j]∣⩽n|p[i] − p[j]| \leqslant \sqrt[]{n}∣p[i]−p[j]∣⩽n​ 的部分就可以完整覆盖所有可能的边。

代码

#include<cstdio>
#include<cmath>
#include<cstring>
#include<queue>
using namespace std;
typedef long long ll;
inline int min(int a,int b)
{return a<b?a:b;
}
inline int max(int a,int b)
{return a>b?a:b;
}
int n,p[50005],rp[50005];
bool vis[50005];
int dis[50005];
ll prim()
{memset(vis,0,sizeof(vis));memset(dis,0x3f,sizeof(dis));int count=0,l,r,k=sqrt(n)+1; ll ans=0;priority_queue<pair<int,int> >q;q.push({0,(1+n)/2});dis[(1+n)/2]=0;while(1){int t=q.top().second;ll val=-q.top().first;q.pop();if(vis[t])continue;vis[t]=1;ans+=val;count++;if(count==n) return ans;l=max(1,t-k),r=min(n,t+k);for(int i=l;i<=r;i++)     //枚举位置 {int dis2=abs((t-i)*(p[t]-p[i]));if(!vis[i] && dis2<dis[i]){q.push({-dis2,i});dis[i]=dis2;}}l=max(1,p[t]-k),r=min(n,p[t]+k);for(int i=l;i<=r;i++)     //枚举值 {int dis2=abs((t-rp[i])*(p[t]-i));if(!vis[rp[i]] && dis2<dis[rp[i]]){q.push({-dis2,rp[i]});dis[rp[i]]=dis2;}}}
}
int main()
{int t; scanf("%d",&t);while(t--){scanf("%d",&n);for(int i=1;i<=n;i++){scanf("%d",p+i);rp[p[i]]=i;}printf("%lld\n",prim());}return 0;
}

1008题

Orgrimmar

原题链接

题目大意

求一棵树最大分离集的大小,换句话说,就是保留树的部分节点和他们之间的边,使得每个节点至多只有一条边与其相连,求点的集合的最大值。

思路

树形 dpdpdp ,可以发现父子节点之间有限制关系。令 fx,0/1/2{f_x,_{0/1/2}}fx​,0/1/2​ 分别表示 xxx 为根的子树中,不选 xxx /选 xxx 但不选子节点连接/选 xxx 且选子节点连接,符合要求的集合最大值。

状态转移:

( yyy 为以 xxx 为根的子节点)

fx,0=sum(max(fy,0,fy,1,fy,2)){f_x,_0}=sum(max({f_y,_0},{f_y,_1},{f_y,_2}))fx​,0​=sum(max(fy​,0​,fy​,1​,fy​,2​))

fx,1=sum(fy,0)+1{f_x,_1}=sum({f_y,_0})+1fx​,1​=sum(fy​,0​)+1

fx,2=sum(fy,0)+max(fy′,1−fy′,0)+1{f_x,_2}=sum({f_y,_0})+max({f_{y'},_1}-{f_{y'},_0})+1fx​,2​=sum(fy​,0​)+max(fy′​,1​−fy′​,0​)+1

代码

#include<bits/stdc++.h>
using namespace std;typedef long long ll;
typedef double db;const int N=5e5+1;int T,n,tot,a,b;
int head[N],ver[2*N],Next[2*N],f[N][3];void add(int x,int y)
{ver[tot]=y;Next[tot]=head[x];head[x]=tot;tot++;
}void dfs(int x,int fa)
{int m0=0,m1=0,m2=0;//表示以x为根的三种情况for(int i=head[x];~i;i=Next[i]){int y=ver[i];if(y==fa) continue;dfs(y,x);//状态转移m0+=max(max(f[y][0],f[y][1]),f[y][2]);m1+=f[y][0];m2=max(m2,f[y][1]-f[y][0]);}f[x][0]=m0;f[x][1]=m1+1;f[x][2]=m1+m2+1;
}int main()
{int size(512<<20);__asm__ ( "movq %0, %%rsp\n"::"r"((char*)malloc(size)+size));scanf("%d",&T);while(T--){scanf("%d",&n);tot=0;for(register int i=1;i<=n;i++)//初始化{head[i]=-1;f[i][0]=0;f[i][1]=0;f[i][2]=0;}for(register int i=1;i<=n-1;i++){scanf("%d%d",&a,&b);add(a,b);add(b,a);}dfs(1,0);printf("%d\n",max(max(f[1][0],f[1][1]),f[1][2]));}exit(0);
}

1011题

Stormwind

题目链接

题目大意

给定一个 n×mn \times mn×m大小的矩形,要求画出尽可能多的线,使得按照这些线切割后得到的小矩形面积均 ⩾k\geqslant k⩾k,问最多能够画多少条线

思路

如果我们确定了某一方向上这条线的间隔时,依靠面积 kkk 即可求出另外一个方向上的间隔。那么我们只需要对某一个方向上的间隔进行枚举。随后计算出另外一个方向上的间隔,分别与 nmn mnm相除即可。值得注意的是,另一方向上的间隔大小应当向上取整,保证小矩形的面积 ⩾k\geqslant k⩾k

代码

#include<iostream>
#include<math.h>
using namespace std;void solve(){int n,m,k;cin>>n>>m>>k;int ans = 0;for(int i = 1;i <= k;i ++){double x = k*1.0 / i;int j = ceil(x);if(i > n || j > m)continue;ans = max(ans,n / i + m / j - 2);}cout<<ans<<endl;
}int main(){ios::sync_with_stdio(false);cin.tie(0);int t;cin>>t;while(t--)solve();system("pause");return 0;
}

2022暑期杭电第八场相关推荐

  1. 2022暑期杭电第十场

    文章目录 1003题 Wavy Tree 题目大意: 思路: 参考代码: 1007题 Even Tree Split 题目大意 思路 代码 1009题 Painting Game 题目大意 分析 代码 ...

  2. 2022暑期杭电第七场

    文章目录 1002题 Independent Feedback Vertex Set 题目大意: 思路: 代码: 1003题 Counting Stickmen 题目大意 思路 代码 1008题 tr ...

  3. 2022暑期杭电第三场

    文章目录 1002题 Boss Rush 题意 分析 代码 1009 Package Delivery 题意 思路 代码 1011题 Taxi 题意: 思路: 代码 1012题 Two Permuta ...

  4. 2022暑期杭电第四场

    文章目录 1001题 Link with Bracket Sequence II 题目大意 思路 代码 1003题 Magic 思路 代码 1001题 Link with Bracket Sequen ...

  5. 2022暑期杭电第九场

    文章目录 1003题 Fast Bubble Sort 题目大意 思路 代码 1007题 Matryoshka Doll--线性DP 题目大意 思路 代码 1008题 Shortest Path in ...

  6. 2019暑期杭电多校HDU6599 I Love Palindrome String

    2019杭电多校HDU6599 I Love Palindrome String 题目链接 I Love Palindrome String Time Limit: 4000/2000 MS (Jav ...

  7. 2022 年杭电多校第八场补题记录

    A Theramore 题意:给定一个长度为 nnn 的 010101 串,每次可以选取一个奇数长度的连续子串进行位置上的翻转,问经过若干次操作能得到的字典序最小的串.n≤5×105n \leq 5\ ...

  8. 2019牛客暑期多校第八场 Flower Dance

    题意 给一些点,找4个点,要求1个点在剩余三个点围成的三角形的内部,问方案数 题解 写得我有种不想碰几何的冲动.... 太迷了,精度迷,同一种意思的不同表达迷,明明那么简洁的思路,为什么写出来这么多特 ...

  9. 2021杭电多校第八场补题

    比赛传送门:Contest Problem List (hdu.edu.cn) 1006)GCD Game 题目翻译:爱丽丝和鲍勃正在玩游戏. 他们轮流操作.有n个数字,a1,a2,...,an.每次 ...

最新文章

  1. CSS中关于margin的理解误区
  2. 理解Java动态代理(1)—找我还钱?我出钱要你的命
  3. 是否可以将Java 8用于Android开发?
  4. Linux平台下的内存泄漏检测
  5. linux的引导流程
  6. MCMC笔记:吉布斯采样(Gibbs)
  7. 高效CNN推理库、多款AlphaGo实现…你们喜欢的Github项目精选又来了!
  8. ES6新特性_Promise封装Ajax请求---JavaScript_ECMAScript_ES6-ES11新特性工作笔记026
  9. 小明用计算机算出58十35,人教版三年级数学下册第三四单元测试卷.docx
  10. gitlab syntax highlighting theme
  11. 初中计算机考试办公软件office2003安装教程
  12. 设置新版谷歌浏览器自动启用flash
  13. 网络摄像机如何安装拾音器?进行同步录音
  14. 海伦公式c语言double,海伦公式
  15. PowerDesigner显示工具栏
  16. ESP8266+电能计量芯片
  17. python连接hive
  18. VBA基础知识整理(数据类型)
  19. 基于JSP的网上购物系统的设计
  20. PJBlog 3.2.9.518 getwebshell 漏洞

热门文章

  1. HDU 5148 Cities 树形DP(背包)
  2. Linux 如何设置代理
  3. 跟着彭亮一起学人工智能之深度学习--零基础学人工智能
  4. 学习OpenCV——Kalman滤波
  5. web程序设计基础——edu实训平台选择判断复习(1)
  6. 怎么做电商运营?浅谈我的电商之路
  7. 二叉树、BTree、B+Tree
  8. Lined List 链表总结 Reverse链表 - 反转(python) leetcode 206 92
  9. 单商户商城系统功能拆解36—分销应用—分销商
  10. 你竟然还不知道电脑上的F1-F12快捷键的作用