A. Forbidden Integer
题意:n能否被分解为若干个整数之和,这些整数在[1,k]内,且不等于x
如果可以,输出方案
思路:分类讨论
- 能分为1则为1的和,x!=1
-
如果x=1,k=1,不行,k=2,如果是偶数,则可以,奇数不行,k>=3,任何都可以
代码:
#include<bits/stdc++.h> using namespace std; #define int long long void solve(){ int n,k,x; cin>>n>>k>>x; set<int >q; if(x!=1){ cout<<"YES\n"; cout<<n<<endl; for (int i = 1; i <=n ; ++i) { cout<<"1 "; } cout<<endl; } else{ if(k==1) { cout << "NO\n"; return; } if(k==2){ if(n%2==1){ cout<<"NO\n"; return; } else{ cout<<"YES\n"; cout<<n/2<<endl; for (int i = 0; i <n/2 ; ++i) { cout<<"2 "; } cout<<endl; return; } } if(k>=3){ if(n!=1){ cout<<"YES\n"; if(n%2==0){ cout<<n/2<<endl; for (int i = 0; i <n/2 ; ++i) { cout<<"2 "; } } else{int cnt=1; cnt+=(n-3)/2; cout<<cnt<<endl; cout<<"3 "; for (int i = 0; i <cnt-1 ; ++i) { cout<<"2 "; } } cout<<endl; } else{ cout<<"NO\n"; } } }
}
signed main(){ ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr); int t; cin>>t; while (t--){ solve(); }
}
# [B. Come Together](https://codeforc.es/contest/1845/problem/B)
## 题意:
给定二维平面上的点,A,B,C
两个人从A,出发分别到B和C,问公共路线是多长
## 思路:
将A点看为原点,然后分别计算x和y两个维度的共同距离
## 代码:
```cpp
#include<bits/stdc++.h>
using namespace std;
#define int long long
void solve(){
int xa,xb,xc,ya,yb,yc;
cin>>xa>>ya>>xb>>yb>>xc>>yc;
xb-=xa;
xc-=xa;
yb-=ya;
yc-=ya;
int ans=1;
if(xb*xc>=0)ans+=min(abs(xb),abs(xc));
if(yb*yc>=0)ans+=min(abs(yb),abs(yc));
cout<<ans<<endl;
}
signed main(){
ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);
int t;
cin>>t;
while (t--){
solve();
}
}
C. Strong Password
题意:
给定数字字符串s,能否构造一共长为m的数字字符串t,满足
- t不是s的子序列
- li<=ti<=ri;
思路:
例如 3141591
- t1 3-5,我们取右边的5,出现次数最晚的,保证后面的取得尽量靠右,贪心
- t2 :1-4 只能取1了
- 倒序的预处理,把每一个位置右边的最近的那个数字的下标求出
代码:
#include<bits/stdc++.h> using namespace std; #define int long long #define PII pair<int,int> void solve(){ string s; string a,b; int n; cin>>s>>n>>a>>b; int l=s.size(); vector<vector<int>>q(l,vector<int>(10)); vector<int>now(10,LLONG_MAX); for (int i = l-1; i >=0 ; --i) { for (int j = 0; j <10 ; ++j) { q[i][j]=now[j]; } int p=s[i]-'0'; now[p]=i; } int cur=-1; for (int i = a[0]-'0'; i <=b[0]-'0' ; ++i) { cur=max(cur,now[i]); } if(cur==LLONG_MAX){ cout<<"yes\n"; return; } for (int i = 1; i <n ; ++i) { int ma=0; for (int j = a[i]-'0'; j <=b[i]-'0' ; ++j) { ma=max(ma,q[cur][j]); } cur=ma; if(cur==LLONG_MAX){ cout<<"yes\n"; return; } } if(cur<l){ cout<<"no\n"; } else{ cout<<"yes\n"; } } signed main(){ ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr); int t=1; cin>>t; while (t--){ solve(); } }
D. Rating System
题意:
给定数组a,从s=0开始,a可能是负数,遍历数组a,并累加ai到s,一旦s>=k,那么后续s=max(s+ai,k)。 问k取多少时,可以让最终的s最大?
思路:
取最小字段和,去掉最小字段和,将其他上移,
代码:
#include<bits/stdc++.h> using namespace std; #define int long long #define PII pair<int,int> void solve(){ int n; cin>>n; vector<int>q(n+1); for (int i = 1; i <=n ; ++i) { cin>>q[i]; q[i]=q[i-1]+q[i]; } int wz=-1,k=0; int cha=1e18; for (int i = 1; i <=n ; ++i) { k=max(k,q[i]); if(cha>=q[i]-k){ cha=q[i]-k; wz=k; } } cout<<wz<<endl; } signed main(){ ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr); int t=1; cin>>t; while (t--){ solve(); } }