2024CCPC哈尔滨部分题解
赛时被评测机卡死了
M.奇怪的上取整
求
第一行一个整数
对于每组数据,一行一个整数
对于每组数据,输出一行一个整数,表示答案。
3
5
451
114514
————————
21T
10251
7075858
思路:如果
所以直接分解出
注意:
#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<math.h>
#include<time.h>
#include<random>
#include<stack>
#include<string>
#define ll long long
#define lowbit(x) (x & -x)
using namespace std;
const ll mod=1e9+7;
ll ksm(ll x,ll y)
{
ll ans=1;
while(y)
{
if(y&1)
{
ans=ans%mod*(x%mod)%mod;
}
x=x%mod*(x%mod)%mod;
y>>=1;
}
return ans;
}
ll gcd(ll x, ll y)
{
if (y == 0)
return x;
else
return gcd(y, x % y);
}
void fio()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
}
ll a[3250000];
int main()
{
fio();
ll t;
cin>>t;
//map<ll,bool>q;
while(t--)
{
//q.clear();
ll n;
cin>>n;
ll cnt=0;
ll u=n;
for(ll i=1;i*i<=n;i++)
{
if(n%i==0)
{
cnt++;
a[cnt]=i;
if(n/i==i)
continue;
else
{
cnt++;
a[cnt]=n/i;
}
}
}
sort(a+1,a+1+cnt);
ll ans=0;
for(ll i=cnt;i>=1;i--)
{
if(n>=a[i])
{
ans+=(n-a[i]+1)*(u/a[i]);
n=a[i]-1;
}
}
ans+=n*u;
cout<<ans<<endl;
}
}
C.在哈尔滨指路
在哈尔滨问路,把行人给的指路方向和位移,转换成你自己的行动方向和位移
第一行一个整数
对于每组数据,第一行一个整数
接下来
表示「往
不相同且不相反(北与南互相相反,西与东互相相反).
对于每组数据,第一行输出一个整数
接下来输出
表示直走到第
本题中你无需最小化
1
2
S 2
E 1
——————————
3 S
Z 2
L
Z 1
思路:本题说那么多就是告诉你它会给出一个人在上北下南左西有东为方位时的走路状况,你只要把他变成第一人称运动按照它给的路径行动即可
暴力模拟,数据给的很宽裕
注意:目前可用的评测机如果endl不用换行符代替,一定会
#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<math.h>
#include<time.h>
#include<random>
#include<stack>
#include<string>
#define ll long long
#define lowbit(x) (x & -x)
#define endl "\n"
using namespace std;
const ll mod=1e9+7;
ll ksm(ll x,ll y)
{
ll ans=1;
while(y)
{
if(y&1)
{
ans=ans%mod*(x%mod)%mod;
}
x=x%mod*(x%mod)%mod;
y>>=1;
}
return ans;
}
ll gcd(ll x, ll y)
{
if (y == 0)
return x;
else
return gcd(y, x % y);
}
void fio()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
}
pair<char,ll>ans[32];
vector<pair<char,ll>>g;
ll pd(char x)
{
if(x=='S')
return 1;
else if(x=='E')
return 2;
else if(x=='N')
return 3;
else
return 4;
}
int main()
{
fio();
ll t;
cin>>t;
while(t--)
{
g.clear();
ll n;
cin>>n;
ll l=0;
for(ll i=1;i<=n;i++)
{
cin>>ans[i].first>>ans[i].second;
ll j=pd(ans[i].first);
if(j==l)
{
g.push_back({'Z',ans[i].second});
continue;
}
if(l==0)
{
if(j==1)
{
l=j;
g.push_back({'S',0});
}
else if(j==2)
{
l=j;
g.push_back({'E',0});
}
else if(j==3)
{
l=j;
g.push_back({'N',0});
}
else
{
l=j;
g.push_back({'W',0});
}
g.push_back({'Z',ans[i].second});
}
else if(l==1)
{
if(j==2)
{
g.push_back({'L',0});
g.push_back({'Z',ans[i].second});
}
else
{
g.push_back({'R',0});
g.push_back({'Z',ans[i].second});
}
}
else if(l==2)
{
if(j==3)
{
g.push_back({'L',0});
g.push_back({'Z',ans[i].second});
}
else
{
g.push_back({'R',0});
g.push_back({'Z',ans[i].second});
}
}
else if(l==3)
{
if(j==4)
{
g.push_back({'L',0});
g.push_back({'Z',ans[i].second});
}
else
{
g.push_back({'R',0});
g.push_back({'Z',ans[i].second});
}
}
else if(l==4)
{
if(j==1)
{
g.push_back({'L',0});
g.push_back({'Z',ans[i].second});
}
else
{
g.push_back({'R',0});
g.push_back({'Z',ans[i].second});
}
}
l=j;
}
cout<<(ll)g.size()-1<<" ";
ll k=0;
for(auto j:g)
{
k++;
if(k==1)
cout<<j.first<<endl;
else
{
if(j.second==0)
cout<<j.first<<endl;
else
cout<<j.first<<" "<<j.second<<endl;
}
}
}
}
G.欢迎加入线上会议!
你想在 MeLink 上组织一次有
会议的组织过程如下:首先由一个人创建会议并加入。随后,已经进入会议的成员可以拉一些自己认识但还没入会的参会者入会,直到所有
你希望确定是否有可能让所有
第一行三个整数
第二行
接下来的
如果无法组织有这
如果可以,则在第一行输出
接下来
你不必最小化
4 5 2
3 4
1 2
1 3
2 3
3 4
2 4
————————————
Yes
2
1 2 2 3
2 1 4
4 5 3
2 4 3
1 2
1 3
2 3
3 4
2 4
——————————
No
思路:其实给的是张图,这个图有
由于多个输出还得是会中人作为邀请方,加上拉朋友只能拉建立变的,所以考虑用
首先对于只能被邀请的点进行
如果一个数的相邻数被打上
来作为是否被拉入会的标志,这样可以避免重复
用两个
注意:如果所有人一开始都是被邀请方,或者
#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<math.h>
#include<time.h>
#include<random>
#include<stack>
#include<string>
#define ll long long
#define lowbit(x) (x & -x)
#define endl "\n"
#define ll long long
using namespace std;
const ll mod=1e9+7;
ll ksm(ll x,ll y)
{
ll ans=1;
while(y)
{
if(y&1)
{
ans=ans%mod*(x%mod)%mod;
}
x=x%mod*(x%mod)%mod;
y>>=1;
}
return ans;
}
ll gcd(ll x, ll y)
{
if (y == 0)
return x;
else
return gcd(y, x % y);
}
void fio()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
}
vector<ll>g[250000],ans[250000];
bool vis[250000];
bool vi[250000];
vector<ll>uo;
void bfs(ll x)
{
queue<ll>q;
q.push(x);
while(!q.empty())
{
ll x=q.front();
q.pop();
if(vis[x])continue;
uo.push_back(x);
vis[x]=1;
vi[x]=1;
for(auto j:g[x])
{
if(vi[j]==0)
{
vi[j]=1;
ans[x].push_back(j);
}
if(vis[j]==0)
{
q.push(j);
}
}
}
}
int main()
{
fio();
ll n,m,k;
cin>>n>>m>>k;
for(ll i=1;i<=k;i++)
{
ll x;cin>>x;
vis[x]=1;
}
while(m--)
{
ll l,r;
cin>>l>>r;
g[l].push_back(r);
g[r].push_back(l);
}
ll s=0;
for(ll i=1;i<=n;i++)
{
if(!vis[i])
{
s=i;
break;
}
}
if(s==0)
{
cout<<"No"<<endl;
return 0;
}
bfs(s);
ll cnt=0;
for(ll i=1;i<=n;i++){
if(vi[i])cnt++;
}
if(cnt!=n)
{
cout<<"No"<<endl;
return 0;
}
cnt=0;
for(ll i=1;i<=n;i++)
{
if(ans[i].size()>0)cnt++;
}
cout<<"Yes"<<endl;
cout<<cnt<<endl;
for(auto i:uo)
{
if(ans[i].size()==0)continue;
cout<<i<<" "<<ans[i].size()<<" ";
for(auto j:ans[i])
{
cout<<j<<" ";
}
cout<<endl;
}
}
k.农场经营
你放弃了编程,来到了三江平原开始务农。在劳动过程中你改掉了作息不规律的毛病,每天你都恰好工作
某天,天气预报说第二天的天气不好,于是在今天你需要调整时间安排以尽快抢收作物。具体地说,你能最多选择一种作物,并删除每天处理这种作物的时间范围限制,即删除后处理该作物的总时间长度可以是
你想知道满足上述条件的情况下,这一天能获得的最大收益是多少。
第一行两个整数
接下来
数据保证
输出一行一个整数,表示这一天能获得的最大收益。
5 17
2 3 4
6 1 5
8 2 4
4 3 3
7 5 5
——————
109
思路:仔细想一下,不难发现删除一个作物并没一个准确的答案(值最大
如何枚举?
不妨想想如果一个作物被删除时(不妨设它单位时间价值为
于是引申出两种状况
1.满足基本情况时,剩下时间用于抢收
这时一定会有
后
时间的价值前缀和数组即可得出,至此答案得出
2.满足基本情况时,剩下时间用于抢收
这时直接用后缀和数组贪心全拿
#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<math.h>
#include<time.h>
#include<random>
#include<stack>
#include<string>
#define ll long long
#define lowbit(x) (x & -x)
#define endl "\n"
#define ll long long
using namespace std;
const ll mod=1e9+7;
ll ksm(ll x,ll y)
{
ll ans=1;
while(y)
{
if(y&1)
{
ans=ans%mod*(x%mod)%mod;
}
x=x%mod*(x%mod)%mod;
y>>=1;
}
return ans;
}
ll gcd(ll x, ll y)
{
if (y == 0)
return x;
else
return gcd(y, x % y);
}
void fio()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
}
struct s
{
ll w;
ll l,r;
}p[250000];
bool cmp(s x,s y)
{
return x.w<y.w;
}
ll sub[250000];
ll gs[250000];
ll pre[250000];
ll to[250000];
ll op[250000];
ll wz[250000];
int main()
{
ll n,m;
cin>>n>>m;
for(ll i=1;i<=n;i++)
{
ll w,l,r;
cin>>w>>l>>r;
p[i].w=w;
p[i].l=l;
p[i].r=r;
}
sort(p+1,p+1+n,cmp);
for(ll i=n;i>=1;i--)
{
sub[i]=p[i].w*p[i].r+sub[i+1];
gs[i]=gs[i+1]+p[i].r;
}
for(ll i=1;i<=n;i++)
{
pre[i]=pre[i-1]+p[i].l*p[i].w;
//cout<<p[i].w<<endl;
to[i]=to[i-1]+p[i].l;
}
ll ans=pre[n];
//cout<<ans<<endl;
for(ll i=1;i<=n;i++)
{
op[i]=op[i-1]+p[n-i+1].r-p[n-i+1].l;
wz[i]=n-i+1;
}
for(ll i=1;i<=n;i++)
{
ll cnt=to[i-1]+gs[i+1];//个数
if(cnt>m)
{
ll u=m-(to[n]-p[i].l);
ll j=lower_bound(op+1,op+1+n,u)-op;
j--;
ll cnt1=m-(to[n]-p[i].l+op[j]);
ans=max(ans,pre[wz[j+1]]-p[i].l*p[i].w+sub[wz[j]]+cnt1*(p[wz[j+1]].w));
}
else
{
ans=max(ans,sub[i+1]+pre[i-1]+(m-cnt)*p[i].w);
}
}
cout<<ans<<endl;
}
J.新能源汽车
有一辆新能源汽车,这辆车有
汽车在出发前每个电瓶都是充满电的。行驶中途会经过
请计算这辆新能源汽车最远可以行驶多少公里。
第一行一个整数
对于每组数据,第一行两个整数
第二行
接下来
对于每组测试数据,保证
对于每组数据,输出一行一个整数,表示这辆车最远可以行驶多少公里。
2
3 1
3 3 3
8 1
2 2
5 2
1 2
2 1
————————
12
9
思路:显然最好的使用电池方法就是,下个充电站是哪个就用哪个电池,如果相应电池没电力,用后面充电站可以充的电池继续前行即可,不能充的电池最好留到最后再用
怎么维护?
考虑开多维
如果一个电池无充电站了,就把他存储起来,最后用,如果还有则用多维
具体还得看看代码
注意:车到了充电站时得考虑目前使用得电池是否被用完
#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<math.h>
#include<time.h>
#include<random>
#include<stack>
#include<string>
#define ll long long
#define lowbit(x) (x & -x)
#define endl "\n"
#define ll long long
using namespace std;
const ll mod=1e9+7;
ll ksm(ll x,ll y)
{
ll ans=1;
while(y)
{
if(y&1)
{
ans=ans%mod*(x%mod)%mod;
}
x=x%mod*(x%mod)%mod;
y>>=1;
}
return ans;
}
ll gcd(ll x, ll y)
{
if (y == 0)
return x;
else
return gcd(y, x % y);
}
void fio()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
}
ll a[325000];
ll b1[325000];//位置
ll b2[325000];//几号电池
map<ll,ll>mp;//还有多少个位置点
set<ll>q[325000];//下个位置点
set<pair<ll,ll>>f;//使用组
//set<pair<ll,ll>>cd;
ll d[3250000];
int main()
{
fio();
ll t;
cin>>t;
while(t--)
{
f.clear();
mp.clear();
ll n,m;
cin>>n>>m;
for(ll i=1;i<=n;i++)
{
cin>>a[i];
d[i]=a[i];
q[i].clear();
}
for(ll i=1;i<=m;i++)
{
ll x,y;
cin>>b1[i]>>b2[i];
q[b2[i]].insert(b1[i]);
mp[b2[i]]++;
}
ll cn=0;
for(ll i=1;i<=n;i++)
{
if(mp[i]==0)cn+=a[i];
else f.insert({*q[i].begin(),i});
}
b1[m+1]=1e18;
ll l=0;//包括自己
ll wz=1;//位置指针
while(1)
{
//讨论还有的
if((ll)f.size()>0)
{
ll su=l;
l=min(l+d[(*f.begin()).second],b1[wz]);
ll k=(*f.begin()).second;d[k]-=(l-su);
ll cs=(*f.begin()).first;
if(b1[wz]==l)wz++;
f.erase(*f.begin());
if(l==cs)
{
d[k]=a[k];mp[k]--;
q[k].erase(cs);
if(mp[k]>0)
{
f.insert({*q[k].begin(),k});
}
else cn+=d[k];
}
else
{
if(l==b1[wz-1])
{
if(d[k]>0)
{
f.insert({*q[k].begin(),k});
}
ll c=b2[wz-1];
d[c]=a[c];mp[c]--;
q[c].erase(l);
if(mp[c]>0)
{
f.insert({*q[c].begin(),c});
}
else cn+=d[c];
}
}
}
else
{
ll su=l;
l=min(l+cn,b1[wz]);
cn-=(l-su);
if(l!=b1[wz])break;
wz++;
ll c=b2[wz-1];
d[c]=a[c];mp[c]--;
q[c].erase(l);
if(mp[c]>0)
{
f.insert({*q[c].begin(),c});
}
else cn+=d[c];
}
}
cout<<l<<endl;
}
}
· [翻译] 为什么 Tracebit 用 C# 开发
· 腾讯ima接入deepseek-r1,借用别人脑子用用成真了~
· Deepseek官网太卡,教你白嫖阿里云的Deepseek-R1满血版
· DeepSeek崛起:程序员“饭碗”被抢,还是职业进化新起点?
· RFID实践——.NET IoT程序读取高频RFID卡/标签