(杭电多校)2023“钉耙编程”中国大学生算法设计超级联赛(5)

1001 Typhoon

计算几何

对于每一个避难点,计算其到所有线段的距离,取min即可

AC代码:

#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<deque>
#include<cmath>
#include<cstdio>
#include<iomanip>
#define endl '\n'
#define eps 1e-9
//#define int long long
using namespace std;
typedef long long ll;
const int N=1e4+10,inf=2e9;
double dist[N];
//向量表示(定义一个结构体,用坐标表示向量)
struct Point {double x,y;double len() const { //模return sqrt(x*x+y*y);}
};
Point operator+(Point a,Point b) { //加法return {a.x+b.x,a.y+b.y};
}
Point operator-(Point a,Point b) { //减法return {a.x-b.x,a.y-b.y};
}
double operator&(Point a,Point b) { //点积return a.x*b.x+a.y*b.y;
}
double operator*(Point a,Point b) { //叉积return a.x*b.y-a.y*b.x;
}
//向量的点积
double dot(Point a,Point b,Point c) {return (b-a)&(c-a);//a,b,c均为点,向量b-a与向量c-a进行点积
}
//向量的叉积
double cross(Point a,Point b,Point c) {return (b-a)*(c-a);
}
int n,m;
void solve() {cin>>m>>n;vector<Point>p(m);for(int i=0; i<m; i++) cin>>p[i].x>>p[i].y;vector<Point>s(n);for(int i=0; i<n; i++) cin>>s[i].x>>s[i].y;vector<double>dis(n,inf);//定义了一个名为dis的变量,它是一个长度为n的vector容器,其中每个元素的初始值都被设置为inffor(int i=1; i<m; i++) {//枚举线段(用向量表示)Point a=p[i-1],b=p[i];//枚举避难所for(int j=0; j<n; j++) {Point c=s[j];double d1=dot(a,b,c);//求向量b-a与向量c-a的点积double d2=dot(b,a,c);//求向量c-b与向量c-a的点积double res;if(d1<0||d2<0) {res=min((c-a).len(),(c-b).len());//点积小于0说明角度是钝角,那么垂足就在线段外,取两点最小值} else {res=cross(a,b,c)/(b-a).len();//求点到线段的垂直距离,为向量b-a与向量c-a叉积再除以向量b-a的模(面积/底)}res=fabs(res);if(res<eps) res=0;//如果答案小于精度,则直接相当于等于0dis[j]=min(dis[j],res);}}cout<<setiosflags(ios::fixed)<<setprecision(4);//保留四位小数,四舍五入,头文件为#include<iomanip>for(int i=0; i<n; i++) cout<<dis[i]<<endl;
}
int main() {ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);int t=1;
//    cin>>t;while(t--)solve();return 0;
}

1006 Touhou Red Red Blue

法一(dp):

AC代码:

#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<cstdio>
#define endl '\n'
#define get(a,b) (a*4+b)
//#define int long long
using namespace std;
typedef long long ll;
const int N=1e5+10,M=16;
int f[N][M];//f[i][j]表示当前球为i,两个袋子的球的状态为j的最大得分,袋子1中的球有4种状态,袋子2中的球也有4种状态,一共4*4=16种状态(0代表没有球,1~3代表球的颜色为R,G,B)
void solve() {string s;cin>>s;int n=s.size();for(int i=1; i<=n; i++) {int c;//表示当前球的颜色,1代表R,2代表G,3代表Bif(s[i-1]=='R') c=1;else if(s[i-1]=='G') c=2;else c=3;for(int j=0; j<M; j++) f[i][j]=f[i-1][j]; //可以选择存储或放弃UFO,我们选择扔掉它//枚举1号袋子的状态和2号袋子的状态,0代表没有球,1~3代表分别代表球的颜色为R,G,Bfor(int a=0; a<=3; a++) {for(int b=0; b<=3; b++) {//如果两个袋子都不为空if(a&&b) {//如果3个球的颜色均相同,那么三个球都消掉,得1分,和消消乐一样if(a==b&&b==c) {//得到一个附加的球放在袋子1里,此时袋子2为空for(int d=1; d<=3; d++) f[i][4*d]=max(f[i][4*d],f[i-1][get(a,b)]+1);}//如果三个球的颜色均不相同,那么3个球都会消失然后会得到两个附加的球,放到袋子1和袋子2中else if(a&&b&&a!=b&&a!=c&&b!=c) {//枚举袋子1的球的颜色for(int d=1; d<=3; d++) {//枚举袋子2的球的颜色for(int e=1; e<=3; e++) {f[i][get(d,e)]=max(f[i][get(d,e)],f[i-1][get(a,b)]);}}}//否则,扔掉袋子1中的球,将袋子2中的球移到袋子1中,并将当前球放到袋子2中else f[i][get(b,c)]=max(f[i][get(b,c)],f[i-1][get(a,b)]);}//if(a&&b)不满足,说明其中一个袋子是空的,//如果a不空,b空,那么就把c放到第二个袋子里else if(a) f[i][get(a, c)] = max(f[i][get(a, c)], f[i - 1][get(a, b)]);//如果a,b袋子均为空,那么就把c放到第一个袋子里else f[i][get(c, 0)] = max(f[i][get(c, 0)], f[i - 1][get(a, b)]);}}}int res=0;for(int i=0; i<M; i++) res=max(res,f[n][i]);cout<<res<<endl;
}
int main() {ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);memset(f[0],-0x3f,sizeof f[0]);//初始化为负无穷,因为后面要取maxf[0][0]=0;//初始状态得分为0,由此开始递推int t=1;cin>>t;while(t--)solve();return 0;
}

法二(贪心):

AC代码:

#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<cstdio>
#define endl '\n'
//#define int long long
using namespace std;
typedef long long ll;
void solve() {string s;cin>>s;int n=s.size();int r=0,g=0,b=0;int res=0;int t=0;//表示这一轮可以自己选几个球,初始为0for(int i=0;i<n;){//这轮可以自选一个球放在袋子1中,然后看后面两个球颜色是否相同if(t==1){if(i==n-1) break;//自选的1个球加上最后一个球一共也才2个球,不足三个球是不能消消乐的,不可以得分了,直接跳出if(s[i]==s[i+1]) t=1,res++;//,如果后两个球颜色相同,那么将这个自选的球颜色变得和后两个球颜色一样,使得三个消消乐消掉,+1分,下一轮进入t=1的状态,即下一轮可以自选一个球放到袋子1中else t=2;//如果后两个球颜色不相同,那么就使得三个球颜色均不相同,下一轮进入t=2的状态,即下一轮可以自选2个球分别放到袋子1和袋子2中i+=2;//跳过本次和下一次,因为连续三个球都消失了}//这轮可以自选两个球放在袋子1和袋子2中,我们完全可以使得这两个球和当前球颜色相同,然后消消乐消掉这三个球,+1分,下一轮else if(t==2){t=1;//凑成3个颜色相同的球,消消乐,下一轮进入t=1的状态res++;i++;//跳过本此}//只有初始状态为t=0,然后接下来就是在t=1和t=2两状态之间转来转去else{if(s[i]=='R') r++;else if(s[i]=='G') g++;else b++;if(r&&g&&b) t=2;//如果三种颜色的球的数量都不为0,那么说明三个球颜色均不相同,那么进入t=2的状态,下一轮可以自选两个球else if(r==3||b==3||g==3) t=1,res++;//如果三个球颜色均相同,那么消消乐,+1分,进入t=1的状态,下一轮可以自选一个球i++;//继续下一轮}}cout<<res<<endl;
}
int main() {ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);int t=1;cin>>t;while(t--)solve();return 0;
}

1007 Expectation(Easy Version)

算期望

根据样例:

一共有n局比赛

通项=组合数(n局中赢哪x局)*n局赢x局的概率*(1^m+2^m+...x^m)

然后遍历1到n,将其全部加起来

也就是:

假设赢一局的概率为p

C(n,1)*p^1*(1-p)^(n-1)*1^m+C(n,2)*p^2*(1-p)^(n-2)*(1^m+2^m)+...C(n,n)*p^n*(1^m+2^m+...+n^m)

由此,我们可以将其分为三个部分A,B以及C

然后呢,每一部分我们都可以不断地累加或者累乘

我们可以发现组合数每次都可以在上一项C(n,i)的基础上乘(n-i)/(i+1)

对于概率这一部分也是同样如此:

再次转换: 

发现每次都是乘a*(b-a)^(-1)

分母始终都是b^n,所以先不用管分母,只需要当全部算完之后,最后除以一个b^n就行了

最后一部分相比之下就很简单,直接加(i+1)^m

AC代码:

#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<deque>
#include<cmath>
#include<cstdio>
#define endl '\n'
#define int long long
using namespace std;
typedef long long ll;
const int mod=998244353;
int n,m,a,b;
inline int qmi(int a,int k){int res=1;while(k){if(k&1) res=(ll)res*a%mod;a=(ll)a*a%mod;k>>=1;}return res;
}
inline int inv(int x){return qmi(x,mod-2);
}
int solve() {cin>>n>>m>>a>>b;int res=0;int k=a*inv(b-a)%mod;int A=n%mod,B=qmi(b-a,n-1)*a%mod,C=1;for(int i=1;i<=n;i++){(res+=A*B%mod*C%mod)%=mod;A=A*(n-i)%mod*inv(i+1)%mod;(B*=k)%=mod;(C+=qmi(i+1,m))%=mod;}return (res*inv(qmi(b,n)))%mod;
}
signed main() {ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);int t=1;cin>>t;while(t--)cout<<solve()<<endl;return 0;
}

1012 Counting Stars 

如图,比如说想要求以1为顶点的2-star图的数量,发现顶点1有三条边,那么就是在三条边中选择两条边的方案数,这样就用到了组合数学

原本我想的是分别求每一个cnt[i],对于每一个cnt[i],枚举所有的顶点,将每个顶点所形成的i-star图的个数加起来,但是会发现这样双重循环就超时了

for (int i = 2; i <= n - 1; i++) {for (int j = 1; j <= n; j++) {(cnt[i] += c[e[j].size()][i]) %= mod;}}

可以换一种思路:枚举所有的顶点,然后我们知道该顶点的度数,就是每枚举一个顶点,就记录以该顶点可以形成的2-star,3-star...的数量,这样做的好处是不会超时,因为根据握手定理

握手定理:

所以度数之和为2*m,为2e6,也就是说时间复杂度不会超过2e6 

    for(int i=1;i<=n;i++){for(int j=2;j<=d[i];j++){(ans[j]+=C(deg[i],j))%=mod;}}

 可以这样理解,加一个cnt++,然后cnt加的次数不会超过2e6

for(int i=1;i<=n;i++){for(int j=2;j<=d[i];j++){(ans[j]+=C(deg[i],j))%=mod,cnt++;}}

现在主要就是求组合数的问题,因为n太大了,所以求组合数不好求

我们发现C(n,1)=n/1,C(n,2)=n*(n-1)/(1*2),C(n,3)=n*(n-1)/(1*2*3)

所以我们可以先预处理阶乘以及阶乘的逆元

AC代码:

#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<deque>
#include<cmath>
#include<cstdio>
#define endl '\n'
//#define int long long
using namespace std;
typedef long long ll;
const int N=1e6+10,mod=1e9+7;
int d[N];
int fac[N],ifac[N];
int ans[N];
int n,m;
//快速幂
int qmi(int a,int k){int res=1;while(k){if(k&1) res=(ll)res*a%mod;a=(ll)a*a%mod;k>>=1;}return res;
}
//求组合数
int C(int n,int m){if(n<m) return 0;return 1ll*fac[n]*ifac[m]%mod*ifac[n-m]%mod;
}
void solve() {cin>>n>>m;for(int i=1;i<=n;i++) d[i]=ans[i]=0;for(int i=0;i<m;i++){int u,v;cin>>u>>v;d[u]++,d[v]++;}for(int i=1;i<=n;i++){for(int j=2;j<=d[i];j++){(ans[j]+=C(d[i],j))%=mod;}}int res=0;for(int i=2;i<=n-1;i++) res^=ans[i];cout<<res<<endl;
}
signed main() {ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);//预处理阶乘以及阶乘的逆元fac[0]=ifac[0]=1;//0的阶乘是1,0的阶乘的逆元也是1for(int i=1;i<N;i++) fac[i]=1ll*fac[i-1]*i%mod;//预处理阶乘ifac[N-1]=qmi(fac[N-1],mod-2);//先求出fac[N-1]的逆元,由于(n+1)!=n!*(n+1)==>n!^(-1)=(n+1)!^(-1)*(n+1),所以也可以通过递推得到阶乘的逆元for(int i=N-2;i>=1;i--) ifac[i]=1ll*ifac[i+1]*(i+1)%mod;int t=1;cin>>t;while(t--)solve();return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/74909.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Linux命令200例】whereis用于搜索以及定位二进制文件

&#x1f3c6;作者简介&#xff0c;黑夜开发者&#xff0c;全栈领域新星创作者✌&#xff0c;阿里云社区专家博主&#xff0c;2023年6月csdn上海赛道top4。 &#x1f3c6;本文已收录于专栏&#xff1a;Linux命令大全。 &#x1f3c6;本专栏我们会通过具体的系统的命令讲解加上鲜…

nexus迁移

数据和配置迁移 打包两个目录&#xff0c;配置nexus-2.13.0-01和数据sonatype-work 数据量大可以split分割之后迁移再合并 大概看下文件目录 [roottest nexus]# tree -L 3 . ├── nexus-2.13.0-01 │ ├── bin │ │ ├── jsw │ │ ├── nexus │ │ …

selenium 遇到更新chorme驱动

打开浏览器,在地址栏输入chrome://version/便可以查看到谷歌当前的版本号 谷歌浏览器驱动的下载网址 http://chromedriver.storage.googleapis.com/index.htmlhttp://chromedriver.storage.googleapis.com/index.html 解压后把chromedriver.exe 放到python安装的目录下&am…

谈一谈缓存穿透,击穿,雪崩

缓存穿透 缓存穿透是指在使用缓存系统时&#xff0c;频繁查询一个不存在于缓存中的数据&#xff0c;导致这个查询每次都要通过缓存层去查询数据源&#xff0c;无法从缓存中获得结果。这种情况下&#xff0c;大量的请求会直接穿透缓存层&#xff0c;直接访问数据源&#xff0c;…

电动自行车上架eBay的UL2849、16CFR1512测试标准

在奥运经济的带动下&#xff0c;今年以来运动自行车消费有较大幅度增长&#xff0c;其中高端消费者对进口自行车需求扩张&#xff0c;上半年竞赛型自行车进口量同比增长49.5%。另外&#xff0c;电助力自行车在国际市场也倍受追捧&#xff0c;国际自行车贸易总额的60%来自中国&a…

嵌入式入门教学——C51

一、前期准备 1、硬件设备 2、软件设备 二、预备知识 1、什么是单片机&#xff1f; 在一片集成电路芯片上集成微处理器、存储器、IO接口电路&#xff0c;从而构成了单芯片微型计算机&#xff0c;及单片机。STC89C52单片机&#xff1a; STC&#xff1a;公司89&#xff1a;所属…

【计算机网络】应用层协议 -- DNS协议

文章目录 1. DNS背景2. 域名简介3. 域名解析过程4. 使用dig查看DNS过程 1. DNS背景 DNS&#xff08;Domain Name System&#xff0c;域名系统&#xff09;协议&#xff0c;是一个用来将域名转化为IP地址的应用层协议。 TCP/IP当中通过IP地址和端口号的方式&#xff0c;来确定…

调试正在运行的程序(Keil)

大家好&#xff0c;我是惊觉。接上一篇调试正在运行的程序(STM32CubeIDE)&#xff0c;今天Keil的实现方法。调试正在运行的程序&#xff0c;属于附着调试&#xff0c;在启动调试器时不会重置单片机的运行状态&#xff0c;从而可以定位死机等问题。没看过上一篇的同学&#xff0…

SystemC的调度器

文章目录 前言调度器初始化evaluatewait updatenotify delta notificationtime notification仿真结束 前言 SystemC是基于C的库&#xff0c;主要用来对 IC 进行功能建模和性能建模。有时也被用来当做 RTL (register transfer level) 级的升级版 HLS(High Level synthesis) 直接…

力扣 416. 分割等和子集

题目来源&#xff1a;https://leetcode.cn/problems/partition-equal-subset-sum/description/ C题解&#xff08;思路来源代码随想录&#xff09; &#xff1a; 背包问题有多种背包方式&#xff0c;常见的有&#xff1a;01背包、完全背包、多重背包、分组背包和混合背包等等。…

JVM基础篇-虚拟机栈

JVM基础篇-虚拟机栈 定义 Java Virtual Machine Stacks &#xff08;Java 虚拟机栈&#xff09; 每个线程运行时所需要的内存&#xff0c;称为虚拟机栈每个栈由多个栈帧&#xff08;Frame&#xff09;组成&#xff0c;对应着每次方法调用时所占用的内存每个线程只能有一个活动…

Manim(一款强大的数学可视化动画引擎)学习历程

相逢情便深&#xff0c;恨不相逢早 第一眼看见上面这种类型的视频我就深深被它的简约清楚所折服&#xff0c;我觉得它完全符合我的审美&#xff0c;我也相信只要了解过制作这种视频的软件的人都会喜欢上它。运用这种风格比较有名的是b站里的一位up主名叫3Blue1Brown&#xff0…

C++ 模板初阶

泛型编程 泛型编程&#xff1a;编写与类型无关的通用代码&#xff0c;是代码复用的一种手段。模板是泛型编程的基础 模板分为&#xff1a;函数模板和类模板 函数模板 概念 函数模板代表了一个函数家族&#xff0c;该函数模板与类型无关&#xff0c;在使用时被参数化&a…

数据结构 | 搜索和排序——排序

目录 一、冒泡排序 二、选择排序 三、插入排序 四、希尔排序 五、归并排序 六、快速排序 排序是指将集合中的元素按照某种顺序排序的过程。 一、冒泡排序 冒泡排序多次遍历列表。它比较相邻的元素&#xff0c;将不合顺序的交换。每一轮遍历都将下一个最大值放到正确的位…

【抽水蓄能电站】基于粒子群优化算法的抽水蓄能电站的最佳调度方案研究(Matlab代码实现)

目录 &#x1f4a5;1 概述 &#x1f4da;2 运行结果 &#x1f389;3 参考文献 &#x1f308;4 Matlab代码、数据、文章讲解 &#x1f4a5;1 概述 文献来源&#xff1a; 摘要&#xff1a;抽水蓄能电站作为当前电力系统重要的储能和调峰电源同时具有填谷、调频、调相、事故备用以…

ETHERNET/IP 转ETHERCAT连接ethercat总线伺服如何控制

捷米JM-EIP-ECAT网关连接到ETHERNET/IP总线中做为从站使用&#xff0c;连接到ETHERCAT总线中做为从站使用&#xff0c;可以同时满足多种工业生产的需求。支持广泛的设备类型&#xff0c;可以和多种不同的设备进行通讯。 技术参数 ETHERNET/IP 技术参数 网关做为 ETHERNET/IP …

记一次 HTTPS 抓包分析和 SNI 的思考

日常听说 HTTPS 是加密协议&#xff0c;那现实中的 HTTPS 流量&#xff0c;是真的完全加密吗&#xff1f; ——答案是&#xff0c;不一定。原因嘛&#xff0c;抓个包就知道了。 我们用 curl 命令触发一下&#xff1a; curl -v https://s-api.37.com.cn/api/xxx * Trying 1…

jmeter使用步骤

jmeter 使用步骤 1&#xff0c;进入jmeter目录中的bin目录&#xff0c;双击jmeter.bat 打开 2&#xff0c;右键test plan 创建线程组 3&#xff0c;配置线程组参数 4&#xff0c;右键刚刚创建的线程组&#xff0c;创建请求&#xff0c;填写请求地址 5&#xff0c;需要携带to…

ES6之Promise、Class类与模块化(Modules)

目录 PromiseClass类extendssuper Modules 模块系统export default 和对应importexport 和 import Promise Promise 是 ES6 引入的一种用于处理异步操作的对象。 它解决了传统回调函数&#xff08;callback&#xff09;模式中容易出现的回调地狱和代码可读性差的问题。 Promis…

【远程桌面软件NoMachine】

Remote Access for Everybody 特色&#xff1a;快速、安全、跨平台、免费且简单易用&#xff0c;尤其是在带宽低、速率慢的网络环境下&#xff0c;NoMachine仍能保持良好的性能。 官网地址为&#xff1a;https://www.nomachine.com/