2021年牛客暑期多校训练营3
2021年牛客暑期多校训练营3
A Guess and lies(待)
题意:
Alice有一个数y在1~n里边,让Bob去猜,每一轮,都可以询问y是否大于等于x,Alice回答是或者不是,但是Alice可以说一次谎。
现在要求对于第一轮询问的x(1~n),当Alice回答yes的时候,Bob需要最少多少轮才能确定y
题解:
注意:
代码:
B Black and white
题意:
有一个n*m的棋盘,要把所有的格子染黑,c[i] [j]表示的是染黑该位置所需要的花费,如果在一个2*2的正方形里,有三块已经被染黑了,那么剩下的那块可以被免费染黑。问将n*m的棋盘染黑所需要的最小花费是多少
题解:
假设(i,j)染成黑色时就把它当做i与j之间的一条可以联通的边,那么现在再假设(i,j), (i+1,j),(i,j+1)这三个边是联通的,那么+1就一定能到达j+1,同理可以推另外三种情况,也就是说只要求得一个最小生成树,任意的i就都能到达任意的j,也就是题中所要求得将所有的格子都给染黑
注意:
横坐标i和j虽然说有相同的数值,但是作为图来讲,是行不通的,所以j+n区别开来,遇事不决,开long long
代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+5;
#define INF 0x3f3f3f3f
typedef long long ll;
ll d[maxn];bool vis[maxn];
struct node{
int v,dis;
node(int _v,ll _dis):v(_v),dis(_dis){}
};
vector<node>Adj[maxn];
ll prim(int n){
fill(d,d+maxn,INF);
memset(vis,false,sizeof(vis));
d[1]=0;
ll ans=0;
for(int i=1;i<=n;i++){
int u=-1;int Min=INF;
for(int j=1;j<=n;j++){//0~n-1号结点
if(vis[j]==false&&d[j]<Min){
Min=d[j];
u=j;
}
}
if(u==-1)return -1;//不能联通
vis[u]=true;
ans+=d[u];
for(int j=0;j<Adj[u].size();j++){
int v=Adj[u][j].v;
if(vis[v]==false&&Adj[u][j].dis<d[v])d[v]=Adj[u][j].dis;
}
}
return ans;
}
int main()
{
int n,m;ll a,b,c,d,p;
scanf("%d %d %lld %lld %lld %lld %lld", &n, &m, &a, &b, &c, &d, &p);
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
a=(a*a*b+a*c+d)%p;
Adj[i].push_back({j+n,a});
Adj[j+n].push_back({i,a});
}
}
printf("%lld",prim(n+m));
return 0;
}
C Minimum grid
题意:
给定一个n*n的网格,其中有m个网格是空的需要填充数值,现在已知了每一行的最大值bi和每一列的最大值,让你求,这个网格里面所有求和的最小值是多少
题解:
详情参考空的位置只能填上bi,ci,0所以可以理解成二分匹配问题
注意:
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=2e3+5;
int match[maxn];bool vis[maxn]={false};
vector<int>g[maxn];
int b[maxn],c[maxn];
int dfs(int u)//匈牙利算法
{
for(auto to:g[u]){
if(vis[to])continue;
vis[to]=1;
if(!match[to]||dfs(match[to])){//没有人和to匹配,或者它的匹配对象被别人抢走了
match[to]=u;
return 1;
}
}
return 0;
}
int main()
{
int n,m,k,x,y;ll ans=0;
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=n;i++){//行
cin>>b[i];ans+=b[i];
}
for(int i=1;i<=n;i++){//列
cin>>c[i];ans+=c[i];
}
while(m--){
scanf("%d%d",&x,&y);
if(b[x]==c[y])g[x].emplace_back(y);//表示x和y之间存在一条边
}
for(int i=1;i<=n;i++){
memset(vis,false,sizeof(vis));
dfs(i);//将n个编号分给它们,让他们自行匹配,
}
for(int i=1;i<=n;i++){
if(match[i]){
ans-=c[i];//可以匹配成功,此时b[i] c[i]所代表的点是一样的,减少一个即可(但是-b[i]的话wa了我也不知道为啥)
}
}
printf("%lld",ans);
return 0;
}
D Count(待)
题意:
题解:
注意:
代码:
E Math
题意:
数1~n内的数字中,有多少对(x,y)满足x*x+y*y=k(xy+1) k为正整数
题解:
详情参考 首先假设满足这个式子,固定x通过韦达定理可以求出也满足条件,因为 和都可行,所以也存在.利用打表的方式,我们发现是恒成立的,代入式子求得所以可以用得到下一个式子,只要按照这个公式递推下去。就能得到满足条件的个数
注意:
虽然给出的是有四个成立的公式,但是因为限制了y>=x,所以只有两个公式
代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn=5e6+5;
typedef long long ll;
ll ans[maxn];
ll cnt=0;
void solve()
{
ll t=1e18;
ans[++cnt]=1;
ll x=2,y=x*x*x,k=x*x;
while(1)
{
if(y>t)break;
ll xx=x,yy=y,m;
while(1){
ans[++cnt]=yy;//一直递推下去
if(__int128(yy)*__int128(k)-__int128(xx)>t)break;
m=xx,xx=yy;yy=k*yy-m;
}
x++;
y=x*x*x;
k=x*x;
}
sort(ans+1,ans+1+cnt);
}
int main()
{
ll n,t;
scanf("%lld",&n);
solve();
while(n--){
scanf("%lld",&t);
printf("%lld\n",upper_bound(ans+1,ans+1+cnt,t)-ans-1);
}
return 0;
}
F 24dian
题意:
有1-13个数,从里边随便选四个数(可重复),通过+ - * / ()最终得到24,特别的是运算的过程中需要出现分数,把所有的情况都按照字典序输出
题解:
详情参考 orz 大佬们都说暴搜就完事了,我就只能copy题解了😅
注意:
代码:
#include<bits/stdc++.h>
using namespace std;
int n,m,flag,cnt,num;
vector<double>v,ans[100009];
bool judge(double x,double y)//表示有小数
{
if(x>(int)x+1e-9)return 1;
if(y>(int)y+1e-9)return 1;
if((x/y)>(int)(x/y)+1e-9)return 1;
return 0;
}
void dfs(int x,int y,vector<double>v){
if(x==n){//n张牌都挑完了
if(fabs(v[0]-m)<1e-8){//此时的v[0]就是最终的运算结果和m进行比较
++flag;
if(y)++cnt;
}
return;
}
int len=v.size();
for(int i=0;i<len;i++){
for(int j=0;j<len;j++){
if(i==j)continue;
vector<double>t;
t.clear();
for(int h=0;h<len;h++)if(h!=i&&h!=j)t.push_back(v[h]);//任选两个值进行运算,剩下的数不变全存入向量里面
t.push_back(v[i]+v[j]);
dfs(x+1,y,t);
t.pop_back();
t.push_back(v[i]-v[j]);
dfs(x+1,y,t);
t.pop_back();
t.push_back(v[i]*v[j]);
dfs(x+1,y,t);
t.pop_back();
t.push_back(v[i]/v[j]);
dfs(x+1,y|judge(v[i],v[j]),t);
t.pop_back();
}
}
}
bool check(vector<double>v)
{
flag=0,cnt=0;
dfs(1,0,v);
if(flag==cnt&&cnt)return 1;//表示的是满足要求有小数的存在且最终答案等于m
return 0;
}
void dfs1(int x,int pre){//随意的放置n个数到数组里面进去,再进行check看是否满足条件
if(x==n+1){
if(check(v))ans[num++]=v;
return ;
}
for(int i=pre;i<=13;i++){//按照字典序安放
v.push_back(i);
dfs1(x+1,i);
v.pop_back();
}
}
int main()
{
cin>>n>>m;
dfs1(1,1);
cout<<num<<endl;
for(int i=0;i<num;i++){
int t=ans[i].size();
for(int j=0;j<t;j++)cout<<ans[i][j]<<" ";
puts("");
}
return 0;
}
G Yu Ling(Ling YueZheng) and Colorful Tree(待)
题意:
题解:
注意:
代码:
H Ling Qiu, Luna and Triple Backpack(待)
题意:
题解:
注意:
代码:
I Kuriyama Mirai and Exclusive Or(待)
题意:
题解:
注意:
代码:
J Counting Triangles
题意:
给定一些边的状态(1或者0)求这些边所形成的三角形当中,相同颜色的边有多少个
题解:
对于每一个点来说都会形成一定的白边和黑边,白边数*黑边数就是对应的异色角的个数,对于一个三角形而言,只存在两种情况,异色或者同色,异色的异色角会有两个,所以只要将异色角的个数/2就是不符合条件的三角形个数,总数减去不符合条件的三角形个数就是要求得值了
注意:
异色三角形个数是(n-1-num)*num,因为自己本身占用了一个点,剩下的点就是n-1了
代码:
#include<bits/stdc++.h>
namespace GenHelper
{
unsigned z1,z2,z3,z4,b,u;
unsigned get()
{
b=((z1<<6)^z1)>>13;
z1=((z1&4294967294U)<<18)^b;
b=((z2<<2)^z2)>>27;
z2=((z2&4294967288U)<<2)^b;
b=((z3<<13)^z3)>>21;
z3=((z3&4294967280U)<<7)^b;
b=((z4<<3)^z4)>>12;
z4=((z4&4294967168U)<<13)^b;
return (z1^z2^z3^z4);
}
bool read() {
while (!u) u = get();
bool res = u & 1;
u >>= 1; return res;
}
void srand(int x)
{
z1=x;
z2=(~x)^0x233333333U;
z3=x^0x1234598766U;
z4=(~x)+51;
u = 0;
}
}
using namespace GenHelper;
using namespace std;
bool edge[8005][8005];
typedef long long ll;
int main() {
ll n;int seed;
cin >> n >> seed;
srand(seed);
ll ans=0;
for (ll i = 0; i < n; i++)
for (ll j = i + 1; j < n; j++)
{
edge[j][i] = edge[i][j] = read();//输入的是1或者0
}
for(int i=0;i<n;i++){
ll num=0;
for(int j=0;j<n;j++){
if(edge[i][j])num++;//对于一个点来说,它所连接的白边个数
}
ans+=(n-1-num)*num/2;//对于每一个点所形成的异色角
}
printf("%lld",n*(n-1)*(n-2)/6-ans);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· winform 绘制太阳,地球,月球 运作规律
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 上周热点回顾(3.3-3.9)
· AI 智能体引爆开源社区「GitHub 热点速览」
· 写一个简单的SQL生成工具