2025 ICPC Nanchang Invitational and Jiangxi Provincial Collegiate Programming Contest
A. Nezha Naohai
点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
using pii=pair<int,int>;
using ll = long long;
using ull = unsigned long long;
const ll inf = 1e18;
const int mod = 998244353;
void solve(){
int a,b,c,d;
cin>>a>>b>>c>>d;
cout<<(a+b+c)*d;
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);
int ct=1;
// cin>>ct;
while(ct--){
solve();
}
}
M. Divide coins
tag:思维题
将前 \(k\) 个放入第一堆,其他的反转并放入第二堆,一定成立,推一下式子就行
点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
using pii=pair<int,int>;
using ll = long long;
using ull = unsigned long long;
const ll inf = 1e18;
const int mod = 998244353;
void solve(){
int n,k;
cin>>n>>k;
for(int i=1;i<=k;i++){
cout<<1;
}
for(int i=1;i<=n-k;i++){
cout<<4;
}
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);
int ct=1;
// cin>>ct;
while(ct--){
solve();
}
}
K. Rotation
tag:思维题
操作一可以转化为,将这个石像逆时针旋转,其他石像不动,参考系也逆时针旋转
一定是使用操作一,将所有石像统一方向后,再操作二
枚举使用操作一把石像统一到 \(0/1/2/3\) 方向即可
点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
using pii=pair<int,int>;
using ll = long long;
using ull = unsigned long long;
const ll inf = 1e18;
const int mod = 998244353;
void solve(){
int n;
cin>>n;
int ans=inf;
vector<int> a(n+1);
for(int i=1;i<=n;i++){
cin>>a[i];
}
for(int dir=0;dir<4;dir++){
int now=0;
int tmp=0;
for(int i=1;i<=n;i++){
now-=(a[i]-dir+4)%4;
tmp+=(a[i]-dir+4)%4;
}
now=(now%4+4)%4;
tmp+=((now-dir)%4+4)%4;
ans=min(ans,tmp);
}
cout<<ans;
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);
int ct=1;
// cin>>ct;
while(ct--){
solve();
}
}
D. Virtuous Pope
tag:离散化,差分
考虑降维的情况,如果是一维的,可以直接做差分
而三维时,直接分别对 \(x,y,z\) 三个轴上做离散化+差分即可
点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
using pii=pair<int,int>;
using ll = long long;
using ull = unsigned long long;
const ll inf = 1e18;
const int mod = 998244353;
void solve(){
int n,a,b,c;
cin>>n>>a>>b>>c;
vector<pii> x(n+1),y(n+1),z(n+1);
for(int i=1;i<=n;i++){
int x1,x2,y1,y2,z1,z2;
cin>>x1>>y1>>z1>>x2>>y2>>z2;
x[i]={min(x1,x2),max(x1,x2)};
y[i]={min(y1,y2),max(y1,y2)};
z[i]={min(z1,z2),max(z1,z2)};
}
int ans=0;
auto f=[&](vector<pii> t)-> int {
vector<int> b;
for(auto [x1,x2]:t){
b.push_back(x1);
b.push_back(x2);
}
sort(b.begin(),b.end());
map<int,int> mp;
int now=1;
for(auto val:b){
if(mp[val]) continue;
mp[val]=now++;
}
vector<int> d(n+10);
for(int i=1;i<=n;i++){
auto [x1,x2]=t[i];
d[mp[x1]]++;
d[mp[x2]+1]--;
}
int ans=0;
for(int i=1;i<=n;i++){
d[i]+=d[i-1];
ans=max(ans,d[i]);
}
return ans;
};
ans=max(ans,f(x));
ans=max(ans,f(y));
ans=max(ans,f(z));
cout<<ans;
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);
int ct=1;
// cin>>ct;
while(ct--){
solve();
}
}
F. Caloric Difference
tag:推公式
推公式发现,\(r\) 越小越好
注意如果用 cout 输出小数,可能输出科学计数法
点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
using pii=pair<int,int>;
using ll = long long;
using ull = unsigned long long;
const ll inf = 1e18;
const int mod = 998244353;
void solve(){
int n,k;cin>>n>>k;
double r0,c0,p,l,r;cin>>r0>>c0>>p>>l>>r;
map<int,int>pos;
vector<double> num(n+1);
vector<double> px(n+1);
for(int i=0;i<k;i++)
{
int pi;double vi;cin>>pi>>vi;
pos[pi]=1;num[pi]=vi;
}
px[1]=p;px[0]=1;
for(int i=2;i<=n;i++)
px[i]=px[i-1]*p;
double ans=0;
for(int i=1;i<=n;i++)
ans+=px[i]*c0;
ans+=r0;
pos[0]=1;num[0]=r0;
for(int i=n;i>=0;i--)
{
if(pos[n-i])
{
ans-=px[i]*num[n-i];
}
else
ans-=px[i]*l;
}
printf("%.8lf",ans);
cout<<endl;
}
signed main(){
// ios::sync_with_stdio(0);
// cin.tie(0);
int ct;
cin>>ct;
while(ct--){
solve();
}
}
G. Exploration
tag:最短路,图上 DP
首先一个定理:\((a/b/c/d)=a/(b*c*d)\) 最终取值不会受到下取整影响(除法全部下取整)
所以就可以处理出,\(f[u][i]\) 表示,以 \(u\) 为起点,连续走 \(i\) 步,的边权累乘最大值
对每一个询问,从小到大枚举 \(i\) 就行
点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
using pii=pair<int,int>;
using ll = long long;
using ull = unsigned long long;
const ll inf = 1e18;
const int mod = 998244353;
void solve(){
int n,m,q;
cin>>n>>m>>q;
vector<vector<pii>> g(n+1);
while(m--){
int u,v,d;
cin>>u>>v>>d;
g[u].push_back({v,d});
}
vector f(n+1,vector<int>(33,1));
for(int i=1;i<=30;i++){
for(int u=1;u<=n;u++){
for(auto [v,d]:g[u]){
f[u][i]=max(f[u][i],d*f[v][i-1]);
}
}
}
while(q--){
int p,x;
cin>>p>>x;
for(int i=1;i<=30;i++){
if(f[p][i]>x){
cout<<i<<endl;
break;
}
}
}
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);
int ct=1;
// cin>>ct;
while(ct--){
solve();
}
}
I. Dating Day
tag: 组合数学,线性 DP
\(f[i]\) 表示,字符串前 \(i\) 个字符,可以变化出的不同个数
需要对每个数,预处理出其最靠左且满足区间和为 \(k\) 的位置
只需要考虑最后一个数的取值即可,不需要考虑容斥
设 \(i\) 最靠左且满足区间和为 \(k\) 的位置为 \(pos\)
状态转移时,如果当前数不变,则 \(f[i]+=f[i-1]\)
如果 \(s[i]\) 由 \(0\) 变成 \(1\),则 \(f[i]+=C(i-pos,k-1)\) ,意思是一个 \(1\) 放到 \(i\),其他 \(1\) 放到前面
如果 \(s[i]\) 由 \(1\) 变成 \(0\),则 \(f[i]+=C(i-pos,k)\) ,意思是一共 \(k+1\) 个 \(1\) 都要放到前面
点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
using pii=pair<int,int>;
using ll = long long;
using ull = unsigned long long;
const ll inf = 1e18;
const int mod = 998244353;
const int N = 1e5+3;
int fact[N],infact[N];
int qmi(int a,int k,int mod){
int res=1;
while(k){
if(k&1) res=res*a%mod;
a=a*a%mod;
k>>=1;
}
return res;
}
void init(){
fact[0]=1;
for(int i=1;i<N;i++) fact[i]=fact[i-1]*i%mod;
infact[N-1]=qmi(fact[N-1],mod-2,mod);
infact[0]=1;
for(int i=N-2;i>=1;i--)
infact[i]=infact[i+1]*(i+1)%mod;
}
int C(int a,int b){
if(a<b || b<0) return 0;
return fact[a]*infact[a-b]%mod*infact[b]%mod;
}
void solve(){
int n,k;
cin>>n>>k;
string s;
cin>>s;
s=" "+s;
vector<int> a(n+1),f(n+1),pre(n+1);
map<int,int> mp;
for(int i=1;i<=n;i++){
a[i]=s[i]-'0';
pre[i]=pre[i-1]+a[i];
if(mp[pre[i]]==0) mp[pre[i]]=i;
}
int p=0;
for(int i=1;i<=n;i++){
if(pre[i]<k) continue;
else if(pre[i]==k){
f[i]=C(i,k);
p=i+1;
}
}
if(p==0){
cout<<0<<endl;
return;
}
for(int i=p;i<=n;i++){
f[i]=f[i-1];
int pos=mp[pre[i]-k]+1;
if(a[i]==0){
f[i]+=C(i-pos,k-1);
}
else{
f[i]+=C(i-pos,k);
}
f[i]%=mod;
}
cout<<f[n]<<endl;
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);
init();
int ct=1;
cin>>ct;
while(ct--){
solve();
}
}

浙公网安备 33010602011771号