2023CCPC山东省赛
2023CCPC山东省赛
2023山东省赛
Dashboard - The 13th Shandong ICPC Provincial Collegiate Programming Contest - Codeforces
I | ⭐ | 循环 |
---|---|---|
A | ⭐ | 排序 |
G | ⭐ | 排序 |
D | ⭐ | 二分 |
L | ⭐⭐ | 简单构造 |
E | ⭐⭐ | 数学 枚举 |
B | ⭐⭐ | 类拓扑排序 |
J | ⭐⭐ | 位运算 |
M | ⭐⭐ | 几何 |
K | ⭐⭐⭐ | 思维&递推 |
F | ⭐⭐⭐ | 线段树优化dp |
C | ⭐⭐⭐ | 类后缀数组 |
H | 娱乐 |
I - Three Dice (枚举)
#include <bits/stdc++.h>
#define bug cout << "***************" << endl
#define look(x) cout << #x << " -> " << x << endl
#define endl '\n'
#define int long long
#define YES cout << "YES" << endl;
#define NO cout << "NO" << endl;
using namespace std;
typedef pair<int, int> PII;
constexpr int N = 100 + 10 , INF = 2e9;
int n,m;
int cnt1,cnt2;
bool check(int x)
{
if(x==1||x==4) return true;
return false;
}
void cal(int x)
{
if(check(x)) cnt1+=x;
else cnt2+=x;
}
void solve()
{
cin>>n>>m;
for(int i=1;i<=6;i++)
{
for(int j=1;j<=6;j++)
{
for(int k=1;k<=6;k++)
{
cnt1=0,cnt2=0;
cal(i);
cal(j);
cal(k);
// cout<<i<<' '<<j<<' '<<k<<' '<<cnt1<<endl;
if(cnt1==n&&cnt2==m)
{
cout<<"Yes\n";
return;
}
}
}
}
cout<<"No\n";
}
signed main()
{
//freopen("check.in","r",stdin);
//freopen("check.out","r",stdin);
ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
solve();
return 0;
}
A - Orders(模拟)
#include <bits/stdc++.h>
#define bug cout << "***************" << endl
#define look(x) cout << #x << " -> " << x << endl
#define endl '\n'
#define int long long
#define YES cout << "YES" << endl;
#define NO cout << "NO" << endl;
using namespace std;
typedef pair<int, int> PII;
constexpr int N = 2e5 + 10 , INF = 2e9;
int n,k;
int num[N],s[N];
pair<int,int> q[N];
void solve()
{
memset(num,0,sizeof num);
cin>>n>>k;
int cnt=1;
map<int,int> mp;
map<int,int> id;
for(int i=1;i<=n;i++)
{
cin>>q[i].first>>q[i].second;
}
sort(q+1,q+n+1);
for(int i=1;i<=n;i++)
{
int a=q[i].first,b=q[i].second;
if(mp[a]==0)
{
mp[a]=cnt;
id[cnt]=a;
cnt++;
}
num[mp[a]]+=b;
}
bool flag=true;
int left=0;
for(int i=1;i<cnt;i++)
{
int add=(id[i]-id[i-1])*k;
// cout<<i<<' '<<left<<' '<<id[i]<<' '<<add<<endl;
if(left+add<num[i])
{
flag=false;
break;
}
else
left=left+add-num[i];
}
if(flag) cout<<"Yes\n";
else cout<<"No\n";
}
signed main()
{
//freopen("check.in","r",stdin);
//freopen("check.out","r",stdin);
ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
int T;
//T=1;
cin>>T;
while(T--)
{
solve();
}
return 0;
}
G - Matching(贪心)
#include <bits/stdc++.h>
#define bug cout << "***************" << endl
#define look(x) cout << #x << " -> " << x << endl
#define endl '\n'
#define int long long
#define YES cout << "YES" << endl;
#define NO cout << "NO" << endl;
using namespace std;
typedef pair<int, int> PII;
constexpr int N = 2e5 + 10 , INF = 2e9;
int n;
int a[N];
map<int,vector<int>> mp;
void solve()
{
mp.clear();
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
mp[i-a[i]].push_back(a[i]);
}
int sum=0;
for(auto it:mp)
{
int len=it.second.size();
for(int i=len-1;i-1>=0;i-=2)
{
int a=it.second[i],b=it.second[i-1];
if(a+b>0) sum+=a+b;
}
}
cout<<sum<<endl;
}
signed main()
{
//freopen("check.in","r",stdin);
//freopen("check.out","r",stdin);
ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
int T;
//T=1;
cin>>T;
while(T--)
{
solve();
}
return 0;
}
L - Puzzle: Sashigane(模拟)
#include <bits/stdc++.h>
#define bug cout << "***************" << endl
#define look(x) cout << #x << " -> " << x << endl
#define endl '\n'
#define int long long
#define YES cout << "YES" << endl;
#define NO cout << "NO" << endl;
using namespace std;
typedef pair<int, int> PII;
constexpr int N = 100 + 10 , INF = 2e9;
int n,x,y;
pair<int,int> c[4];
int sz;
int dx[4]={-1,-1,1,1},dy[4]={-1,1,-1,1};
bool check(int x,int y)
{
if(x>=1&&x<=n&&y>=1&&y<=n) return true;
return false;
}
void solve()
{
cin>>n>>x>>y;
for(int i=0;i<4;i++)
{
c[i].first=x;
c[i].second=y;
}
sz=1;
vector<vector<int>> ans(n,vector<int>(4));
int cnt=0;
while(sz!=n)
{
// cout<<"初始:\n";
// for(int i=0;i<4;i++)
// {
// cout<<c[i].first<<' '<<c[i].second<<endl;
// }
for(int i=0;i<4;i++)
{
int a=c[i].first+dx[i],b=c[i].second+dy[i];
if(check(a,b))
{
c[i].first=a;
c[i].second=b;
// cout<<"a:"<<a<<' '<<c[3-i].first<<endl;
int min_x=min(a,c[3-i].first);
int max_x=max(a,c[3-i].first);
int min_y=min(b,c[3-i].second);
int max_y=max(b,c[3-i].second);
// cout<<"四角:\n";
// cout<<min_x<<' '<<min_y<<' '<<max_x<<' '<<max_y<<endl;
c[0].first=min_x,c[0].second=min_y;
c[1].first=min_x,c[1].second=max_y;
c[2].first=max_x,c[2].second=min_y;
c[3].first=max_x,c[3].second=max_y;
sz++;
ans[cnt][0]=a;
ans[cnt][1]=b;
ans[cnt][2]=-dx[i]*sz+dx[i];
ans[cnt++][3]=-dy[i]*sz+dy[i];
// cout<<a<<' '<<b<<' '<<-dx[i]*sz<<' '<<-dy[i]*sz<<endl;
break;
}
}
// cout<<"sz:"<<sz<<endl;
// for(int i=0;i<4;i++)
// {
// cout<<c[i].first<<' '<<c[i].second<<endl;
// }
}
cout<<"Yes\n";
cout<<cnt<<endl;
for(int i=0;i<cnt;i++)
{
for(int j=0;j<4;j++)
{
cout<<ans[i][j]<<" \n"[j==3];
}
}
}
signed main()
{
//freopen("check.in","r",stdin);
//freopen("check.out","r",stdin);
ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
solve();
return 0;
}
D - Fast and Fat (二分+贪心)
思路:
求最慢速度的最大值 考虑二分答案
对于答案x,如何判断是否满足条件
假设所有人中小于速度x的有p人,大于等于速度x的有q人
对于q个人来说 可以背负的最大体重是 自己的体重+自己的速度-速度x
所以要满足x是最小速度 首先p要小于等于q
而且 对于p中的每个人 体重不能超过q中每个人背负的最大体重
让q中背负体重从大到小排序 与p中体重从大到小排序 一一对应 如果有一个不满足说明x不能是最小速度
#include <bits/stdc++.h>
#define bug cout << "***************" << endl
#define look(x) cout << #x << " -> " << x << endl
#define endl '\n'
#define int long long
#define YES cout << "YES" << endl;
#define NO cout << "NO" << endl;
using namespace std;
typedef pair<int, int> PII;
constexpr int N = 2e5 + 10 , INF = 2e9;
int n;
PII a[N],b[N];
bool check(int x)
{
vector<int> s1,s2;
for(int i=1;i<=n;i++)
if(a[i].first>=x) s1.push_back(a[i].second+a[i].first-x);
for(int i=1;i<=n;i++)
if(b[i].first<x) s2.push_back(b[i].second);
if(s1.size()<s2.size()) return false;
for(int i=0;i<s2.size();i++)
if(s1[i]<s2[i]) return false;
return true;
}
void solve()
{
cin>>n;
for(int i=1;i<=n;i++)
{
int v,w;
cin>>v>>w;
a[i]=b[i]={v,w};
}
sort(a+1,a+n+1,[](PII &a,PII &b){
return a.first+a.second>b.first+b.second;
});
sort(b+1,b+n+1,[](PII &a,PII &b){
return a.second>b.second;
});
int l=a[1].first,r=a[1].second;
for(int i=1;i<=n;i++)
{
l=min(a[i].first,l);
r=max(a[i].first,r);
}
while(l<r)
{
int mid=(l+r+1)>>1;
if(check(mid)) l=mid;
else r=mid-1;
}
cout<<r<<endl;
}
signed main()
{
//freopen("check.in","r",stdin);
//freopen("check.out","r",stdin);
ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
int T;
//T=1;
cin>>T;
while(T--)
{
solve();
}
return 0;
}
E - Math Problem (数学、枚举)
思路:
应该先进行除法在进行乘法 因为先乘再除数没有改变
进行p次乘法后 n的范围为[kp*n,kp*n+kp-1],长度为kp
只要这个范围里面包括 m 的倍数即可停止乘法操作,至多操作logk(m)次
所以枚举除法操作进行几次然后枚举乘法操作进行几次即可
#include <bits/stdc++.h>
#define bug cout << "***************" << endl
#define look(x) cout << #x << " -> " << x << endl
#define endl '\n'
#define int long long
#define YES cout << "YES" << endl;
#define NO cout << "NO" << endl;
using namespace std;
typedef pair<int, int> PII;
constexpr int N = 1000 + 10 , INF = 2e9;
int n,k,m,a,b;
void solve()
{
cin>>n>>k>>m>>a>>b;
if(n%m==0)
{
cout<<0<<endl;
return;
}
if(k==1)
{
cout<<-1<<endl;
return;
}
int ans=1e18,cost=0;
while(1)
{
int base=n%m,len=1;
for(int i=0; ;i++)
{
int left=(m-base)%m;
if(left<len)
{
ans=min(ans,cost+i*a);
break;
}
base=base*k%m;
len*=k;
}
if(n==0) break;
n/=k;
cost+=b;
}
cout<<ans<<endl;
}
signed main()
{
//freopen("check.in","r",stdin);
//freopen("check.out","r",stdin);
ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
int T;
cin>>T;
while(T--)
{
solve();
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!