2024牛客寒假算法基础集训营5
A.
总数-1的个数
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N=1e5+10;
#define inf 0x3f3f3f3f
void solve() {
int n;cin>>n;
int ans=0;
for(int i=1,x;i<=n;i++){
cin>>x;
if(x==1)continue;
ans++;
}
cout<<ans;
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int left=1;
//cin>>left;
while(left--){
solve();
}
}
B.
第一个数能放的都放在前面,然后后面的数取相邻间最小的
最后一个数最后也可以放
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N=1e5+10;
#define inf 0x3f3f3f3f
void solve() {
int n;cin>>n;
vector<int>a(n+2);
for(int i=1;i<=n;i++)cin>>a[i];
a[0]=inf;a[n+1]=inf;
int last=inf;
int ans=0;
for(int i=1;i<=n;i++){
if(last>=a[i]){
ans+=a[i]-1;
last=0;
}else{
ans+=last;
last=a[i]-last-1;
}
}
if(last)ans+=last;
cout<<ans;
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int left=1;
//cin>>left;
while(left--){
solve();
}
}
G.
n方去枚举每个数与哪些数可以满足条件,然后二分图跑
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N=2e6+10;
#define inf 0x3f3f3f3f
bool is_prime[N];//是否是质数,0为是,1为不是
int prime[N];//质数数组
int top=1;//质数的下标
int min_p[N];//最小质因数数组
void get_prime(int n){
for(int i=2;i<=n;i++){
if(!is_prime[i]){//是质数
prime[top]=i;//存质数
min_p[i]=i;//质数的最小质因数是本身
top++;//下标后移
}
for(int j=1;j<top;j++){//最小到达遍历质数数组
if(i*prime[j]>n)break;
is_prime[i*prime[j]]=1;//标记质数的倍数即合数
min_p[i*prime[j]]=prime[j];//质数的倍数的最小质因数是该质数
if(i%prime[j]==0)break;//若i是之前质数的倍数,说明这个倍数会在后面的循环内被筛去,无需继续循环
}
}
}
vector<int>l[N/2];//边信息
int boy[N/2];//匹配信息
int used[N/2];//标记数组
int k,m;//配对信息,m点集,n点集
bool find(int i){
for(int j=0;j<l[i].size();j++){
if(!used[l[i][j]]){
used[l[i][j]]=1;
if(!boy[l[i][j]]||find(boy[l[i][j]])){
boy[l[i][j]]=i;
return true;
}
}
}
return false;
}
void solve() {
int n;cin>>n;
get_prime(2*n+10);
//vector<int>ans(n+1);//vis(n+1,0);
//int cnt=0;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
// if(vis[j])continue;
if(is_prime[i+j]==0){
l[i].push_back(j);
}
}
}
memset(boy,0,sizeof(boy));
int sum=0;
for(int i=1;i<=n;i++){
memset(used,0,sizeof(used));
if(find(i))sum++;
}
if(sum>=n){
for(int i=1;i<=n;i++)cout<<boy[i]<<' ';
cout<<'\n';
}else cout<<"-1\n";
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int left=1;
//cin>>left;
while(left--){
solve();
}
}
H.
1-n的顺序序列,相差为1
让n从1开始遍历到谁能够得到质数
比如n+3是质数,那么n-1和4也一定是质数
这样两两配对后若还有1个数,则把这个数和与n配对的那个数之前的那些数暴力二分图
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N=2e6+10;
#define inf 0x3f3f3f3f
bool is_prime[N];//是否是质数,0为是,1为不是
int prime[N];//质数数组
int top=1;//质数的下标
int min_p[N];//最小质因数数组
void get_prime(int n){
for(int i=2;i<=n;i++){
if(!is_prime[i]){//是质数
prime[top]=i;//存质数
min_p[i]=i;//质数的最小质因数是本身
top++;//下标后移
}
for(int j=1;j<top;j++){//最小到达遍历质数数组
if(i*prime[j]>n)break;
is_prime[i*prime[j]]=1;//标记质数的倍数即合数
min_p[i*prime[j]]=prime[j];//质数的倍数的最小质因数是该质数
if(i%prime[j]==0)break;//若i是之前质数的倍数,说明这个倍数会在后面的循环内被筛去,无需继续循环
}
}
}
vector<int>l[N/2];//边信息
int boy[N/2];//匹配信息
int used[N/2];//标记数组
int k,m;//配对信息,m点集,n点集
bool find(int i){
for(int j=0;j<l[i].size();j++){
if(!used[l[i][j]]){
used[l[i][j]]=1;
if(!boy[l[i][j]]||find(boy[l[i][j]])){
boy[l[i][j]]=i;
return true;
}
}
}
return false;
}
void solve() {
int n;cin>>n;
get_prime(2*n+10);
//vector<int>ans(n+1);//vis(n+1,0);
//int cnt=0;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
// if(vis[j])continue;
if(is_prime[i+j]==0){
l[i].push_back(j);
}
}
}
memset(boy,0,sizeof(boy));
int sum=0;
for(int i=1;i<=n;i++){
memset(used,0,sizeof(used));
if(find(i))sum++;
}
if(sum>=n){
for(int i=1;i<=n;i++)cout<<boy[i]<<' ';
cout<<'\n';
}else cout<<"-1\n";
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int left=1;
//cin>>left;
while(left--){
solve();
}
}
I.
模拟
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N=1e5+10;
#define inf 0x3f3f3f3f
void solve() {
int t,a,k;cin>>t>>a>>k;
if(t==0){
cout<<abs(a);
return ;
}
if(a==0){
cout<<abs(t);
return ;
}
if(t>0&&a>0){
if(t>=a){
cout<<t;
}else {
cout<<(a+(a-t));
}
return ;
}
if(t<0&&a<0){
t=-t;a=-a;
if(t>=a){
cout<<t;
}else {
cout<<(a+(a-t));
}
return ;
}
if(abs(a)<=k){
cout<<(2*abs(a)+abs(t));
}else{
cout<<(3*abs(t)+2*abs(a));
}
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int left=1;
//cin>>left;
while(left--){
solve();
}
}
M.
考虑如何分割
要么竖着切割,要么错位1个分割
两种方法都跑,能1次解决就一次,最多两次
特判n=1和2
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N=1e5+10;
#define inf 0x3f3f3f3f
void solve() {
int n;cin>>n;
vector<int>a(n+1),b(n+1);
for(int i=1;i<=n;i++)cin>>a[i];
for(int i=1;i<=n;i++)cin>>b[i];
if(n==1){
cout<<"-1\n";return ;
}
if(n==2){
if(a[1]==b[1]) {
cout << "-1\n";
return;
}
cout<<"1\n";return ;
}
for(int i=2;i<=n-1;i++){
if(a[i]==b[i]){
cout<<"1\n";return ;
}
}
for(int i=1;i<n;i++){
if(a[i]==b[i+1]||b[i]==a[i+1]){
cout<<"1\n";return ;
}
}
cout<<"2\n";
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int left=1;
cin>>left;
while(left--){
solve();
}
}