A 造数
思路:逆向求解,循环此算法:(奇数--,cnt++,偶数/2,cnt++,到2时cnt++,直接-2)
AC代码:
#include<bits/stdc++.h>
using namespace std;
void solve(int n){
int cnt = 0;
while(n!=0){
if(n%2){
n--;
cnt++;
}
else if(n==2){
n-=2;
cnt++;
}
else{
n/=2;
cnt++;
}
}
cout<<cnt<<endl;
}
int main(){
//while(1){
int n;
cin>>n;
solve(n);
//}
return 0;
}
F 两难抉择新编
思路:运用异或运算的性质,暴力就好(悲
AC代码:
#include<bits/stdc++.h>
using namespace std;
#define int long long
int n;
int arr[200005];
int ans = 0;
signed main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>arr[i];
ans = ans^arr[i];
}
int f = ans;
for(int i=1;i<=n;i++){
for(int j=1;j<=(n/i);j++){
int aa = arr[i]+j;
int bb = arr[i]*j;
ans = max(ans,f^arr[i]^aa);
ans = max(ans,f^arr[i]^bb);
}
}
cout<<ans<<endl;
return 0;
}
G 旅途的终点
思路:贪心+优先队列维护
K次神力一定是给K个消耗最大的国家使用(命啊,贱命啊,剩一条吊着就行啊),因为题目的数字给到了10^18,所以不能用vis[]标记的方法,改用优先队列进行维护
AC代码:
#include<bits/stdc++.h>
using namespace std;
#define int long long
int a[200005];
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n,m,k;
cin>>n>>m>>k;
for(int i=1;i<=n;i++) cin>>a[i];
priority_queue<int,vector<int>,greater<int> > p,q;
for(int i=1;i<=k;i++){
p.push(a[i]);
}
int ans = p.size();
int flag = 1;
for(int i=k+1;i<=n;i++){
int x = 0;
p.push(a[i]);
q=p;
// pp=p;
// int ps = pp.size();
// for(int i=0;i<ps;i++){
// cout<<pp.top()<<" ";
// pp.pop();
// }
// cout<<endl;
while(q.size()>k){
x += q.top();
q.pop();
}
if(x>=m){
ans += i-k-1;
flag = 0;
break;
}
}
if(flag) ans += n-k;
cout<<ans<<endl;
return 0;
}
H 两难抉择
思路:找出最大的那个数,输出max(sum,sum-最大+最大*n)
AC代码:
#include<bits/stdc++.h>
using namespace std;
#define int long long
signed main(){
int mi = 0;
int n;
int sum = 0;
cin>>n;
int x;
for(int i=0;i<n;i++){
cin>>x;
sum += x;
mi = max(mi,x);
}
int a = sum+n;
int b = sum-mi+mi*n;
cout<<max(a,b);
return 0;
}
I 除法移位
思路:将最大数移到首位所需的最小次数(注意一定要倒着找!!!)
AC代码:
#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,t;
signed main(){
cin>>n>>t;
vector<int> arr(n,0); int xx = n-1;
for(int i=0;i<n;i++) cin>>arr[i];
vector<int> brr = arr;
sort(brr.begin(),brr.end());
int ans = -1;
if(t==0) ans=0;
while(ans == -1){
int i;
for(i=n-1;i>-1;i--){
if(arr[i] == brr[xx]) break;
}
if(i==0) ans=0;
else if((n-i)<=t) ans=n-i;
else xx--;
}
cout<<ans;
return 0;
}
思路:所有点打散再拼接成两坨,左右数字尽量接近答案最大
AC代码:
#include<bits/stdc++.h>
using namespace std;
#define int long long
signed main(){
int n,m;
cin>>n>>m;
for(int i=0;i<m;i++){
int a,b;
cin>>a>>b;
}
if(n%2){
int t=n/2;
n-=t;
cout<<n*t;
}
else{
int t=n/2;
cout<<t*t;
}
return 0;
}