牛客周赛59(A,B,C,D,E二维循环移位,F范德蒙德卷积)

news2024/9/17 7:43:25

比赛链接

官方讲解

很幸运参加了内测,不过牛客这消息推送天天发广告搞得我差点错过内测消息,差点进小黑屋,好在开赛前一天看到了。

这场不难,ABC都很签到,D是个大讨论,纯屎,E是需要对循环移位进行处理和转化,转化后很简单,如果看不懂我写的可以看官方的讲解,画图可能会比较好理解,F是数学,需要分开计算贡献,最后再来一步范德蒙德卷积优化,知识点不难就是比较冷门。


A TD

思路:

签到

code:

#include <iostream>
#include <cstdio>
using namespace std;

int a,b;

int main(){
	cin>>a>>b;
	cout<<1.0*a/b;
	return 0;
}

B 你好,这里是牛客竞赛

思路:

如果是以 https://www.nowcoder.com 或者 www.nowcoder.com 作为前缀开头的话,那就是牛客主站,输出 Nowcoder。如果是以 https://ac.nowcoder.com 或者 ac.nowcoder.com 作为前缀开头的话,那就是牛客竞赛,输出 Ac。剩下的就是其他网站。

找子串可以用 s t r i n g string string 自带的 f i n d find find 方法,它会返回第一个匹配的子串的下标,作为前缀开头的话就看 f i n d find find 的值是否为 0 0 0 即可,是 0 0 0 就说明一开始就匹配上了,也就是前缀。

code:

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

int T;
string s;

int main(){
	cin>>T;
	while(T--){
		cin>>s;
		if(s.find("https://ac.nowcoder.com")==0 || s.find("ac.nowcoder.com")==0)
			cout<<"Ac"<<endl;
		else if(s.find("https://www.nowcoder.com")==0 || s.find("www.nowcoder.com")==0)
			cout<<"Nowcoder"<<endl;
		else cout<<"No"<<endl;
	}
	return 0;
}

C 逆序数

思路:

一个序列里对任意的一对数只有正序和逆序两种关系,不是逆序就是正序。在一个序列里任取两个数的取法有 C n 2 = n ∗ ( n − 1 ) 2 C_n^2=\dfrac{n*(n-1)}2 Cn2=2n(n1) 种可能,也就是一共有这么多个关系,除了 k k k 个逆序,剩下的就有 n ∗ ( n − 1 ) 2 − k \dfrac{n*(n-1)}2-k 2n(n1)k 个正序。

而翻转之后,正序就会变成逆序,逆序变成正序,不管你这个集合是怎么凑的,翻转之前是 k k k 个逆序, n ∗ ( n − 1 ) 2 − k \dfrac{n*(n-1)}2-k 2n(n1)k 个正序,翻转之后就是 n ∗ ( n − 1 ) 2 − k \dfrac{n*(n-1)}2-k 2n(n1)k 个逆序, k k k 个正序。

code:

#include <iostream>
#include <cstdio>
using namespace std;

long long n,k;

int main(){
	cin>>n>>k;
	cout<<n*(n-1)/2-k<<endl;
	return 0;
}

D 构造mex

思路:

我嘞个大讨论啊,屎题。我已经能预想到那好看的通过率了。

我讨论的方法如下:

  1. k = 0 k=0 k=0 时,就尽量让每个数都是 1 1 1,最后一个数放剩余的还没用掉的值。
    1. s < n s<n s<n 时,这时甚至做不到让每个位置都是 1 1 1,一定会有位置为 0 0 0,因此无解
    2. s ≥ n s\ge n sn 时,就可以用上面的思路来凑。
  2. k ≠ 0 k\not=0 k=0 时,先凑出 0 , 1 , 2 , … , k − 1 0,1,2,\dots,k-1 0,1,2,,k1,这样 m e x mex mex 就等于 k k k 了,然后再把剩余的值放在后面,剩余位置就都放 0 0 0。前面 0 , 1 , 2 , … , k − 1 0,1,2,\dots,k-1 0,1,2,,k1 一共 k k k 个数,总和为 t o t = k ∗ ( k − 1 ) 2 tot=\dfrac{k*(k-1)}2 tot=2k(k1)
    1. 有可能 s < t o t s<tot s<tot,这时连前面的 k k k 个数都凑不出来,因此无解。
    2. 有可能 s = t o t s=tot s=tot,这时正好没有剩余的数,因此凑出前 k k k 个数后后面都可以补 0 0 0
      1. 当位置个数 n < k n<k n<k 时,位置不够,因此无解。
      2. n ≥ k n\ge k nk 时,位置够,用上面的方法来凑。
    3. 有可能 s − t o t = k s-tot=k stot=k,这时不能直接把剩余的值 s − t o t s-tot stot 放在后面,必须先拆出一个单独的 1 1 1 ,然后再把 s − t o t − 1 s-tot-1 stot1 放下,后面补 0 0 0
      1. 有可能 s − t o t = k = 1 s-tot=k=1 stot=k=1,这时做不到先拆出一个单独的 1 1 1 ,然后再把 s − t o t − 1 s-tot-1 stot1 放下,因为也会冲突,这时无解。
      2. 有可能位置个数不够,即 n < k + 2 n<k+2 n<k+2,这时无解
      3. 剩余情况,按上面的方法来凑。
    4. 按上面的方法来凑需要至少 k + 1 k+1 k+1 个位置,如果位置不够则无解,否则按上面的方法来凑。

code:

#include <iostream>
#include <cstdio>
using namespace std;
typedef long long ll;

ll T,s,n,k;

int main(){
	cin>>T;
	while(T--){
		cin>>s>>n>>k;
		if(k==0){
			if(s<n)cout<<"NO"<<endl;
			else {
				cout<<"YES"<<endl;
				cout<<s-n+1<<" ";
				for(int i=1;i<=n-1;i++)cout<<1<<" ";
				cout<<endl;
			}
		}
		else {
			ll tot=k*(k-1)/2;
			if(s<tot)cout<<"NO"<<endl;
			else {
				if(k==1 && s-tot==1)cout<<"NO"<<endl;
				else {
					if(s-tot==0){
						if(n<k)cout<<"NO"<<endl;
						else {
							cout<<"YES"<<endl;
							for(int i=0;i<k;i++)cout<<i<<" ";
							for(int i=k+1;i<=n;i++)cout<<0<<" ";
							cout<<endl;
						}
					}
					else if(s-tot==k){
						if(n<k+2)cout<<"NO"<<endl;
						else {
							cout<<"YES"<<endl;
							for(int i=0;i<k;i++)cout<<i<<" ";
							cout<<1<<" "<<s-tot-1<<" ";
							for(int i=k+3;i<=n;i++)cout<<0<<" ";
							cout<<endl;
						}
					}
					else {
						if(n<k+1)cout<<"NO"<<endl;
						else {
							cout<<"YES"<<endl;
							for(int i=0;i<k;i++)cout<<i<<" ";
							cout<<s-tot<<" ";
							for(int i=k+2;i<=n;i++)cout<<0<<" ";
							cout<<endl;
						}
					}
				}
			}
		}
	}
	return 0;
}

E 小红的X型矩阵

思路:

对一个正方形,我们可以统计出它两个对角线上有多少个 1 1 1,对角线上的位置总个数减去对角线上 1 1 1 的个数就是对角线上 0 0 0 的个数,也就是需要用操作 1 1 1 0 0 0 翻转成 1 1 1 的次数。然后再统计出一共有多少个 1 1 1,减去对角线上 1 1 1 的个数就是对角线以外其他位置上 1 1 1 的个数,也就是需要需要用操作 1 1 1 1 1 1 翻转成 0 0 0 的次数。这个快速统计对角线上 1 1 1 的个数可以用斜着的前缀和来做。

这个循环移动我们可以看作是移动这两个对角线,但是我们对角线一旦循环移动了就会断成两段,就很难计数了,而且对于 n n n 为奇数的情况,两个对角线还会有交点,我们交点只能算一次,但是用前缀和来快速计数就会算两次,很麻烦。

这时我们可以参考数组的循环移位,把数组复制一遍到后面。我们可以把这个正方形往 x , y x,y xy 轴各复制一遍,这样从 ( i , j ) (i,j) (i,j) ( i + n − 1 , j + n − 1 ) (i+n-1,j+n-1) (i+n1,j+n1) 的这个矩形就相当于原矩形向左循环移位 i − 1 i-1 i1 次,向上循环移位 j − 1 j-1 j1 次。

我们枚举矩形的左上角坐标 ( i , j ) (i,j) (i,j),这样对每一个正方形都对应一个循环移位后的正方形,统计所有正方形的答案,然后取最小值即可。

注意 n n n 为奇数的时候,中间会有一个交点,前缀和对两个对角线计数会重复算一次,需要减掉。

code:

#include <iostream>
#include <cstdio>
using namespace std;
const int maxn=1005;

int n,a[maxn<<1][maxn<<1],s1[maxn<<1][maxn<<1],s2[maxn<<1][maxn<<1],tot;

int main(){
	cin>>n;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++){
			cin>>a[i][j];
			tot+=a[i][j];
			a[i+n][j]=a[i][j+n]=a[i+n][j+n]=a[i][j];
		}
	
	for(int i=1;i<=2*n;i++)
		for(int j=1;j<=2*n;j++)
			s1[i][j]=s1[i-1][j-1]+a[i][j];
	for(int i=1;i<=2*n;i++)
		for(int j=1;j<=2*n;j++)
			s2[i][j]=s2[i-1][j+1]+a[i][j];
	
	int ans=1e9;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++){//枚举左上角坐标 
			int t=0,t1=s1[i+n-1][j+n-1]-s1[i-1][j-1],t2=s2[i+n-1][j]-s2[i-1][j+n];
			t=t1+t2;
			if(n&1){
				t-=a[i+n/2][j+n/2];
				ans=min(ans,(2*n-1)-t+tot-t);
			}
			else {
				ans=min(ans,2*n-t+tot-t);
			}
		}
	cout<<ans<<endl;
	return 0;	
}

F 小红的数组回文值

思路:

内测时写了一个很神秘的暴力,结果过了,然后被加强数据卡死了。。。这个暴力其实本质上和正解差不多,就差一个范德蒙德卷积优化kuso。

这个题是求所有子序列的回文值,但是我们显然不可能枚举出所有的子序列,所以我们不妨转化一下视角,看每一对数的贡献。

当一对数不同,并且在某一个回文串中正好对应,那么它就会产生一次贡献,假设第 i i i 个位置和第 j j j 个位置的数在某一个回文串中对应,并且 a i ≠ a j a_i\not=a_j ai=aj。怎么算出所有满足这两个数对应的回文串呢?

我们可以在前 i − 1 i-1 i1 个位置和后 n − j n-j nj 个位置同时选出 k k k 个数,在中间的 j − i − 1 j-i-1 ji1 个数中选若干个数,这样就凑出一个 a i a_i ai a j a_j aj 对应的回文串了。

假设前后各有 x , y x,y x,y 个数,也就是 x = i − 1 , y = n − j x=i-1,y=n-j x=i1,y=nj,那么选取的方案数就是 ∑ k = 0 m i n { x , y } C x k ∗ C y k ∗ 2 n − x − y − 2 \sum_{k=0}^{min\{x,y\}} C_x^k*C_y^k*2^{n-x-y-2} k=0min{x,y}CxkCyk2nxy2

因为 n = 2000 n=2000 n=2000,所以我们可以枚举 i , j i,j i,j,算出对应的 x , y x,y x,y,然后再枚举 k k k。这样就是一个 O ( n 3 ) O(n^3) O(n3) 的算法,会 T T T,但是如果我们如果能把枚举 k k k 的过程优化掉,就可以压成 O ( n 2 ) O(n^2) O(n2) 的了。

还真能, 2 n − x − y − 2 2^{n-x-y-2} 2nxy2 k k k 无关,可以提出来,前面的这个 ∑ k = 0 m i n { x , y } C x k ∗ C y k \sum_{k=0}^{min\{x,y\}} C_x^k*C_y^k k=0min{x,y}CxkCyk,我们不妨设 x < y x<y x<y(不然就交换 x , y x,y x,y),则 = ∑ k = 0 x C x k ∗ C y k = ∑ k = 0 x C x x − k ∗ C y k =\sum_{k=0}^{x} C_x^k*C_y^k=\sum_{k=0}^{x} C_x^{x-k}*C_y^k =k=0xCxkCyk=k=0xCxxkCyk 这一步可以通过范德蒙德卷积优化,得到 = C x + y x =C_{x+y}^{x} =Cx+yx。范德蒙德卷积讲解可以看 OI wiki。

code:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>
using namespace std;
const int maxn=2e3+5;
typedef long long ll;
const ll mod=1e9+7;

int n,a[maxn];
ll qpow(ll a,ll b){
	ll ans=1,base=a%mod;
	b%=mod;
	while(b){
		if(b&1)ans=ans*base%mod;
		base=base*base%mod;
		b>>=1;
	}
	return ans;
}
ll inv(ll x){return qpow(x,mod-2);}

ll fac[maxn],ifac[maxn];
ll C(ll x,ll y){//C_x^y
	if(x<y)return 0;
	return fac[x]*ifac[y]%mod*ifac[x-y]%mod;
}

ll calc(ll x,ll y){
	if(x>y)swap(x,y);
	return qpow(2,n-x-y-2)*C(x+y,x)%mod;
}

int main(){
	cin>>n;
	for(int i=1;i<=n;i++)cin>>a[i];
	
	fac[0]=1;
	for(int i=1;i<=2000;i++)fac[i]=fac[i-1]*i%mod;
	ifac[2000]=inv(fac[2000]);
	for(int i=2000;i>=1;i--)ifac[i-1]=ifac[i]*i%mod;
	
	ll ans=0;
	for(int i=1;i<=n;i++)
		for(int j=i+1;j<=n;j++)
			if(a[i]!=a[j])
				ans=(ans+calc(i-1,n-j));
	cout<<(ans%mod+mod)%mod<<endl;
	return 0;
}

内测时成功卡AC的 O ( n 3 ) O(n^3) O(n3) 暴力代码(虽然最后还是被卡掉了):

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>
using namespace std;
const int maxn=2e3+5;
typedef long long ll;
const ll mod=1e9+7;

int n,a[maxn],b[maxn];
ll qpow(ll a,ll b){
	ll ans=1,base=a%mod;
	b%=mod;
	while(b){
		if(b&1)ans=ans*base%mod;
		base=base*base%mod;
		b>>=1;
	}
	return ans;
}
ll inv(ll x){return qpow(x,mod-2);}

ll fac[maxn],ifac[maxn];
ll C(ll x,ll y){//C_x^y
	if(x<y)return 0;
	return fac[x]*ifac[y]%mod*ifac[x-y]%mod;
}

vector<int> c[maxn];

ll calc(ll x,ll y){
	ll ans=0;
	for(int i=0;i<=min(x,y);i++)
		ans=(ans+C(x,i)*C(y,i))%mod;
	return qpow(2,n-x-y-2)*ans%mod;
}

int main(){
	cin>>n;
	for(int i=1;i<=n;i++)cin>>a[i];
	memcpy(b,a,sizeof(b));
	sort(b+1,b+n+1);
	int tot=unique(b+1,b+n+1)-b-1;
	auto find=[&](int x)->int{return lower_bound(b+1,b+n+1,x)-b;};
	for(int i=1;i<=n;i++)a[i]=find(a[i]);
	for(int i=1;i<=n;i++)c[a[i]].push_back(i);
	
	fac[0]=1;
	for(int i=1;i<=2000;i++)fac[i]=fac[i-1]*i%mod;
	ifac[2000]=inv(fac[2000]);
	for(int i=2000;i>=1;i--)ifac[i-1]=ifac[i]*i%mod;
	
	ll ans=0;
	for(int i=1;i<=n;i++){
		ans=(ans+C(n,i)*(i/2)%mod)%mod;
	}
	for(int i=1;i<=n;i++){
		for(int l=0;l<c[i].size();l++)
			for(int r=l+1;r<c[i].size();r++){
				ans=(ans-calc(c[i][l]-1,n-c[i][r]))%mod;
			}
	}
	cout<<(ans%mod+mod)%mod<<endl;
	return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

25届计算机专业选题推荐-基于python的线上拍卖会管理系统【python-爬虫-大数据定制】

&#x1f496;&#x1f525;作者主页&#xff1a;毕设木哥 精彩专栏推荐订阅&#xff1a;在 下方专栏&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; 实战项目 文章目录 实战项目 一、基于python的线上拍卖会管理…

Window下编译OpenJDK17

本文详细介绍Window下如何编译OpenJDK17&#xff0c;包含源码路径&#xff0c;各工具下载地址&#xff0c;严格按照文章中的步骤来操作&#xff0c;你将获得一个由自己亲手编译出的jdk。 一、下载OpenJDK17源码 下载地址&#xff1a;GitHub - openjdk/jdk at jdk-1735 说明&a…

碰撞检测 | 详解矩形AABB与OBB碰撞检测算法(附ROS C++可视化)

引言 在复杂的人工智能系统和机器人应用中,碰撞检测(Collision Detection)作为一项基础技术,扮演着至关重要的角色。无论是在自动驾驶车辆中防止车祸的发生,还是在机器人导航中避免障碍物,碰撞检测的精度和效率都直接决定了系统的可靠性和安全性。在游戏开发、虚拟现实、…

USART—串口通讯

USART—串口通讯 大纲 串口通讯协议简介STM32 的 USART 简介USART 功能框图USART 初始化结构体详解 具体案例 串口通讯协议简介 物理层 串口通讯的物理层有很多标准及变种&#xff0c;我们主要讲解 RS-232 标准&#xff0c;RS-232 标准主要规定了信号的用途、通讯接口以及…

SpringCache之本地缓存

针对不同的缓存技术&#xff0c;需要实现不同的cacheManager&#xff0c;Spring定义了如下的cacheManger实现。 CacheManger 描述 SimpleCacheManager 使用简单的Collection来存储缓存&#xff0c;主要用于测试 ConcurrentMapCacheManager 使用ConcurrentMap作为缓存技术&…

spring揭秘20-spring事务02-编程式事务与声明式事务管理

文章目录 【README】【1】编程式事务管理【1.1】使用PlatformTransactionManager进行编程式事务管理【1.2】使用TransactionTemplate进行编程式事务管理【1.3】基于Savepoint的嵌套事务 【2】声明式事务管理【2.1】基于xml的声明式事务【2.1.1】使用ProxyFactory&#xff08;Pr…

【基础篇】应届毕业生必备:机器学习面试题指南【1】

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推荐------》 一、AI应用软件开发实战专栏【链接】 项目名称项目名称1.【人脸识别与管理系统开发…

【软件工程】软件开发模型

三、瀑布模型 四、几种软件开发模型的主要特点 题目 判断题 选择题 小结

房贷计算及比较

本博客主要介绍&#xff1a; 1. 等额本金计算公式 2. 等额本息计算公式 3. 对比两种还款方式 4. 本示例:贷款金额为35万&#xff0c; 期限12年&#xff0c;年利率4.9% 等额本金计算 import matplotlib.pyplot as plt import matplotlib matplotlib.rcParams[font.sans-s…

day1 QT

作业 #include "mywidget.h"MyWidget::MyWidget(QWidget *parent): QWidget(parent) {//设置窗口大小this->resize(1025,533);//固定窗口大小this->setFixedSize(1025,533);//设置窗口背景色,设置弧度//this->setStyleSheet("background-image:url(E:/…

JS_数据类型

一、JS的数据类型 数值类型 数值类型统一为 number,不区分整数和浮点数 字符串类型 字符串类型为 string 和JAVA中的String相似,JS中不严格区分单双引号,都可以用于表示字符串 布尔类型 布尔类型为boolean 和Java中的boolean相似,但是在JS的if语句中,非空字符串会被转换为…

SuperMap iManger 单个镜像更新流程

1. 下载镜像 docker pull registry.cn-beijing.aliyuncs.com/supermap/common-dashboard-api:11.1.1-240802-amd64 label 没区分架构&#xff0c;在 x64 环境 pull arm64 镜像 通过 --platformarm64 参数可以实现 docker pull mariadb:10.5.26 --platformarm64 # 指定拉取ar…

【重学 MySQL】十九、位运算符的使用

【重学 MySQL】十九、位运算符的使用 示例检查权限添加权限移除权限 在 MySQL 中&#xff0c;位运算符允许你直接在整数类型的列或表达式上进行位级操作。这些操作对于处理那些需要在二进制表示上进行直接修改或比较的场景特别有用&#xff0c;比如权限管理、状态标记等。 &…

20240909 每日AI必读资讯

重磅&#xff01;TIME揭榜2024全球AI 100人&#xff1a;奥特曼、黄仁勋、姚期智、王小川等上榜 - TIME正式揭晓了第二届100位最具影响力AI人物名单&#xff01;「领导者」榜单中&#xff0c;有我们耳熟能详的OpenAI CEO Sam Altman、英伟达CEO黄仁勋。而字节跳动联合创始人兼C…

数据结构(邓俊辉)学习笔记】排序 7——希尔排序:Shell 序列 + 输入敏感性

文章目录 1.邮资问题2. 定理K3.逆序对 1.邮资问题 此前曾经讲到希尔排序在对矩阵逐列排序时所使用的算法本身未必需要十分高效&#xff0c;而更重要的是应该具有输入敏感的特性&#xff0c;因此我们更倾向于使用插入排序。那么背后的具体原因又当如何解释呢&#xff1f;这里的…

ubuntu16.04 vim使用中文出现乱编文档处理

问题现象 vim 编译文件时出现乱码问题 解决方法 1. 中文语言包安装: apt-get install language-pack-zh-hans 2. 配置环境变量:echo "export LC_ALLzh_CN.UTF-8" >>/etc/bash.bashrc 3. 修改当前环境的字符集 /etc/default/locale cat /etc/default/locale…

国内外网络安全政策动态(2024年8月)

▶︎ 1.《关于进一步加强智能网联汽车准入、召回及软件在线升级管理的通知》公开征求意见 8月1日&#xff0c;工业和信息化部装备工业一司联合市场监管总局质量发展局组织编制了《关于进一步加强智能网联汽车准入、召回及软件在线升级管理的通知&#xff08;征求意见稿&#…

事务的原理

1. 什么是事务 事务就是一个包含多个步骤的事情&#xff0c;这些步骤要么都做好&#xff0c;要么都别做。 2. ACID 事务都跟ACID相关&#xff0c;注意这里说的是“相关”&#xff0c;而不是一定都“满足”。全都严格满足&#xff0c;是“刚性事务”&#xff0c;部分满足或一…

240908-Python代码实现6种与DBGPT-Knowledge-API的交互方式

A. Chat模式 # import asyncio # from dbgpt.core import ModelRequest # from dbgpt.model.proxy import OllamaLLMClient# clientOllamaLLMClient()# print(asyncio.run(client.generate(ModelRequest._build("qwen2:1.5b", "你是谁&#xff1f;"))))imp…

Debug-027-el-tooltip组件的使用及注意事项

前言&#xff1a; 这两天&#xff0c;碰到这个饿了么的el-tooltip比较多。这个组件使用起来也挺简单的&#xff0c;常用于展示鼠标 hover 时的提示信息。但是有一些小点需要注意。这里不再机械化的介绍文档&#xff0c;不熟悉的话可以先看一下&#xff1a; https://element-pl…