比赛链接:HBCPC2024
还是和 @cyx20110930 组的队,只不过用我的号交的。(rk. 26)这次我也橙了 开心.jpg
由于 @cyx20110930 在车上,电脑又快没电了,所以他只上线 1h。但居然写了 2 题,还口胡出了2 题,%%%
其实H题也很简单,一个 dfs。但由于我水平太菜,时间不够,没来及写。大家可以去尝试一下。
安利一波 @cyx20110930 的题解。
题目意思
输入,输出乘积最大的两个数
使得
。
思路
数学题,秒了。直接先算出的值。然后为了让
最大,直接输出
和
即可。
代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
signed main(){
int T;
cin>>T;
while(T--){
int x,y;
cin>>x>>y;
int gcd=__gcd(x,y);
int lcm=x*y/gcd;
cout<<lcm/gcd<<' '<<1<<endl;
}
return 0;
}
这题是 CYX 写的。所以copy一下他的题解。(bushi
题目意思
平面上有一些点,问你用其中至少三个点组成的图形的面积最小是多少,如果组不了,输出 -1。
思路
很明显最小的一定是三角形。
证明:任何一个正 n 边形,都可以分成一个三角形,与一个正 n-1 边形,自然三角形的面积小于这个正 n 边形。
所以直接暴力枚举三角形用海伦公式求面积即可。
代码
孩子不判三点共线,多半是废了!
#include <bits/stdc++.h>
using namespace std;
struct node{
double x,y;
}po[1000005];
void solve(){
double ans=0x3f;
int n;
cin>>n;
for(int i=1;i<=n;i++){
cin>>po[i].x>>po[i].y;
}
for(int i=1;i<=n;i++){
for(int j=i+1;j<=n;j++){
for(int z=j+1;z<=n;z++){
double sum=po[j].x*po[z].y-po[z].x*po[j].y+po[i].x*po[j].y-po[j].x*po[i].y-po[i].x*po[z].y+po[z].x*po[i].y;
sum=abs(sum);
if (sum != 0){
ans=min(ans,sum/2.0);
}
}
}
}
if (ans==0x3f){
cout<<-1<<endl;
}
else{
cout<<ans<<endl;
}
}
int main(){
int t;
while(t--){
solve();
}
}
签到。
题目意思
一共 n 人,每人可以选 b 美刀的 Grilled Chicken Burger Set 或 a 美刀的 Spicy Chicken Burger Set。其中选 Grilled Chicken Burger Set 有 x 人,问总共花了几美刀?
代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
int main(){
int T;
cin>>T;
while(T--){
int n,x,a,b;
cin>>n>>x>>a>>b;
cout<<(n-x)*a+x*b<<endl;
}
return 0;
}
原神,启动!(我不玩原神)
题目意思
在一局围棋中,给你黑方与白方每一步的落子,问你每一步黑白双方有几个子被吃?
思路
很简单,我们可以每一步落子之后,对这个棋子周围的五个位置的联通块处理即可。
代码
#include <bits/stdc++.h>
using namespace std;
const int dx[4]={0,0,1,-1};
const int dy[4]={1,-1,0,0};
int board[30][30],ans[10],n=19;
bool used[30][30];
void bfs(int x,int y){
int col=board[x][y];
queue<pair<int,int>> que;
vector<pair<int,int>> v;
que.push(make_pair(x,y));
used[x][y]=true;
bool ok=false;
while(!que.empty()){
auto [x,y]=que.front();
que.pop();
v.push_back(make_pair(x,y));
for(int i=0;i<4;i++){
int nx=x+dx[i],ny=y+dy[i];
if(nx<1 || nx>n || ny<1 || ny>n)
continue;
if(board[nx][ny]==-1)
ok=true;
if(board[nx][ny]!=col || used[nx][ny])
continue;
que.push(make_pair(nx,ny));
used[nx][ny]=true;
}
}
if(!ok){
for(auto &[x,y]:v){
board[x][y]=-1;
ans[col]++;
}
}
return;
}
void solve(int col,vector<pair<int,int>> &v){
memset(used,0,sizeof(used));
for(auto &[x,y]:v){
if(x<1 || x>n || y<1 || y>n)
continue;
if(used[x][y])
continue;
if(board[x][y]!=col)
continue;
bfs(x,y);
}
for(auto &[x,y]:v){
if(x<1 || x>n || y<1 || y>n)
continue;
if(used[x][y])
continue;
if(board[x][y]!=1^col)
continue;
bfs(x,y);
}
return;
}
int main(){
memset(board,-1,sizeof(board));
int m;
cin>>m;
for(int i=1;i<=m;i++){
int x,y;
cin>>x>>y;
int col=i%2;
board[x][y]=col;
ans[1]=ans[0]=0;
vector<pair<int,int>> v;
for(int i=0;i<4;i++)
v.push_back(make_pair(x+dx[i],y+dy[i]));
v.push_back(make_pair(x,y));
solve(col^1,v);
cout<<ans[0]<<' '<<ans[1]<<endl;
}
return 0;
}
是 @cyx20110930 写的,所以跟我无关(bushi
他的题解:here
题目意思
有一个序列,问对于所有 1 到 n 的排列
,算出的
... 的期望对 998244353 的取模。
思路
结论:平均数。
证明
记答案为,
若 a 数组有 n 项,期望为
证毕!还是平均数。
代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define mod 998244353
int qmi(int a,int b,int p){
int res=1;
while(b){
if(b&1) res=res*a%p;
b>>=1;
a=a*a%p;
}
return res;
}
int main(){
int n;
cin>>n;
int x,ans=0;
for(int i=1;i<=n;i++){
cin>>x;
ans+=x;
}
ans=ans%mod;
ans=ans*qmi(n,mod-2,mod)%mod;
cout<<ans;
}
题目意思
给定起点和终点,求起点到终点的最短路径,任意两点的路径为
思路
首先特判,输出0。
假设
- 当
时,代价是 y。
- 当 x 和 y 不互质是,可以 x→gcd(x,y)→y,代价为 x+y
- 当 x 和 y 互质时:中间经过的点必然都是质数。让经过的质数越小越好。
代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
int lcm(int a,int b){
return a*b/__gcd(a,b);
}
void solve(){
int a,b;
cin>>a>>b;
if(a==b){
cout<<0<<endl;
return;
}
vector<int> A,B;
A.push_back(2);
B.push_back(2);
A.push_back(a);
B.push_back(b);
for(int i=2;i<=a/i;i++){
if(a%i==0){
int x=i,y=a/i;
if(x!=1)
A.push_back(x);
if(y!=1)
A.push_back(y);
}
}
for(int i=2;i<=b/i;i++){
if(b%i==0){
int x=i,y=b/i;
if(x!=1)
B.push_back(x);
if(y!=1)
B.push_back(y);
}
}
int ans = lcm(a,b);
for(auto &x:A){
int now=lcm(a,x)+lcm(b,x);
ans=min(ans,now);
for(auto &y:B){
int now1=lcm(a,x)+lcm(x,y)+lcm(y,b);
int now2=lcm(a,x)+lcm(x,2)+lcm(y,2)+lcm(y,b);
ans=min({ans,now1,now2});
}
}
for(auto &x:B){
int now=lcm(a,x)+lcm(b,x);
ans=min(ans,now);
for(auto &y:A){
int now1=lcm(a,x)+lcm(x,y)+lcm(y,b);
int now2=lcm(a,x)+lcm(x,2)+lcm(y,2)+lcm(y,b);
ans=min({ans,now1,now2});
}
}
cout<<ans<<endl;
return;
}
int main(){
int T;
cin>>T;
while(T--)
solve();
return 0;
}
友情提醒:不要Ctrl C+Ctrl V