造数
真的是白WA啊,如果他是0,那么就输出0。如果他是2或1,那么直接输出1。如果是跟一般的数,先让他去除二,如果他除二后是奇数,那么就减去1在除二,否则继续除二。一直计算到他是2或者1,结束。
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
#define inf 0x3f3f3f3f3f3f3f3f
#define pii pair<int,int>
void solve(){
int n;
cin>>n;
int sum=0;
if(n==0){
cout<<0<<endl;
return;
}
if(n==2 or n==1){
cout<<1<<endl;
return;
}
while(1){
if(n%2==1){
n-=1;
sum++;
}
n/=2;
sum++;
if(n%2==1){
n-=1;
sum++;
}
if(n==2 or n==1){
sum++;
break;
}
}
cout<<sum<<endl;
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);cout.tie(nullptr);
int oyyo=1;
// cin>>oyyo;
while(oyyo--) {
solve();
}
return 0;
}
图上计数(Easy)
眼力题,无算法的吓人题(有算法我也写不出)。
直接去分块就好了。因为可以任意删边, 所以最后的联通块可以任意组合 那么两个连通块数量最接近时最大
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
#define inf 0x3f3f3f3f3f3f3f3f
#define pii pair<int,int>
void solve(){
int n,m;
cin>>n>>m;
for (int i = 0; i < m; i++) {
int u, v;
cin >> u >> v;
}
int cnt = 0;
if(n==1){
cout<<0<<endl;
return;
}
if(n%2==0){
cout<<(n/2)*(n/2)<<endl;
return;
}else{
cout<<(n/2)*(n/2+1)<<endl;
}
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);cout.tie(nullptr);
int oyyo=1;
// cin>>oyyo;
while(oyyo--) {
solve();
}
return 0;
}
两难抉择
如果,数组的最大值是1,那么就让1去加上n这样乘出来会比只乘n大一,如果是另一个,那么取最大值,把他乘上n这个样就是最大值。
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
#define inf 0x3f3f3f3f3f3f3f3f
#define pii pair<int,int>
void solve(){
int n;
cin>>n;
vector<int>a(n);
int max1=0,min1=inf;
int sum=0;
for(int i=0;i<n;i++){
cin>>a[i];
max1=max(max1,a[i]);
min1=min(min1,a[i]);
sum+=a[i];
}
if(max1!=1){
sum-=max1;
sum+=max1*n;
cout<<sum<<endl;return;
}else{
sum+=n;
cout<<sum<<endl;
return;
}
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);cout.tie(nullptr);
int oyyo=1;
// cin>>oyyo;
while(oyyo--) {
solve();
}
return 0;
}
两难抉择新编
级数内容1/n+2/n+3/n+4/n+.......=......
2e5算出的结果是1e6范围。所以可以暴力枚举。
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
#define inf 0x3f3f3f3f3f3f3f3f
#define pii pair<int,int>
void solve(){
int n;
cin>>n;
vector<int>a(n);
int max1=-1,min1=inf;
int k1=0,k2=0;
int sum=0;
for(int i=0;i<n;i++){
cin>>a[i];
sum^=a[i];
if(a[i]>max1){
max1=a[i];
k1=i;
}
if(a[i]<min1){
min1=a[i];
k2=i;
}
}
if(max1==1){
sum^=1;
sum^=(1+n);
cout<<sum<<endl;
return;
}
int max2=sum;
for(int i=0;i<n;i++){
for(int j=1;j<=n/(i+1);j++){
int x=sum;
x^=a[i];
x^=(a[i]*j);
max2=max(x,max2);
}
}
cout<<max2<<endl;
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);cout.tie(nullptr);
int oyyo=1;
// cin>>oyyo;
while(oyyo--) {
solve();
}
return 0;
}
除法移位
把最大的数移到最前面最大, 相同大小取操作次数少的。不要用double!!!!!!!!
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
#define inf 0x3f3f3f3f3f3f3f3f
#define pii pair<int,int>
void solve(){
int n,t;
cin>>n>>t;
vector<int >a(n);
for(int i=0;i<n;i++){
cin>>a[i];
}
int max1=a[0];
int k=0;
reverse(a.begin(),a.end());
for(int i=0;i<min(n-1,t);i++){
if(a[i]>max1){
k=i+1;
max1=a[i];
}
}
cout<<k<<endl;
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);cout.tie(nullptr);
int oyyo=1;
// cin>>oyyo;
while(oyyo--) {
solve();
}
return 0;
}
旅途的终点
二分答案,我写了个题单,但还是没写出来。下面提供三个方法,这个的二分会爆long long,记得中途退出。换乘int128会无脑解。
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
#define inf 0x3f3f3f3f3f3f3f3f
#define pii pair<int,int>
const int mod=998244353;
int n,m,k;
int a[1000005];
int b[1000005];
bool check(int x){
if(k>=x){
return true;
}
memset(b,0,sizeof(b));
for(int i=1;i<=x;i++){
b[i]=a[i];
}
sort(b+1,b+x+1);
int m1=m;
for(int i=1;i<=x-k;i++){
m1-=b[i];
if(m1<=0) return 0;
}
return 1;
}
void solve(){
cin>>n>>m>>k;
for(int i=1;i<=n;i++){
cin>>a[i];
b[i]=a[i];
}
if(k>=n){
cout<<n<<endl;
return;
}
int l=0,r=n;
int ans=0;
int mid;
while(l<=r){
mid=(l+r)>>1;
if(check(mid)){
ans=mid;
l=mid+1;
}else{
r=mid-1;
}
}
cout<<ans<<endl;
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);cout.tie(nullptr);
int oyyo=1;
//cin>>oyyo;
while(oyyo--) {
solve();
}
return 0;
}
int128要用快读, 快写。
#include<bits/stdc++.h>
using namespace std;
#define int __int128
#define endl '\n'
#define inf 0x3f3f3f3f3f3f3f3f
#define pii pair<int,int>
const int mod=998244353;
int n,m,k;
int a[1000005];
int b[1000005];
inline void scan(__int128 &x){
bool f=1;x=0;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-') f=!f;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
x=(f?x:-x);return;
}
void print(__int128 num)
{//递归调用,实现从高位向低位输出
if(num>9)
print(num/10);
putchar(num%10+'0');
}
bool check(int x){
if(k>=x){
return true;
}
memset(b,0,sizeof(b));
for(int i=1;i<=x;i++){
b[i]=a[i];
}
sort(b+1,b+x+1);
int m1=m;
for(int i=1;i<=x-k;i++){
m1-=b[i];
}
if(m1>0){
return true;
}else{
return false;
}
}
void solve(){
scan(n),scan(m),scan(k);
for(int i=1;i<=n;i++){
scan(a[i]);
b[i]=a[i];
}
if(k>=n){
print(n);
return;
}
int l=0,r=n;
int ans=0;
int mid;
while(l<=r){
mid=(l+r)>>1;
if(check(mid)){
ans=mid;
l=mid+1;
}else{
r=mid-1;
}
}
print(ans);
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);cout.tie(nullptr);
int oyyo=1;
//cin>>oyyo;
while(oyyo--) {
solve();
}
return 0;
}
优先队列做法。
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
#define inf 0x3f3f3f3f3f3f3f3f
#define pii pair<int,int>
void solve(){
int n,m,k;
cin>>n>>m>>k;
vector<int>a(n+1);
vector<int>b(n+1);
priority_queue<int,vector<int>,less<int>>q;
for(int i=1;i<=n;i++){
cin>>a[i];
}
int res=0;
int z=0;
for(int i=1;i<=n;i++){
q.push(a[i]);
res+=a[i];
while(res>=m){
int x=q.top();
z++;
res-=x;
q.pop();
}
b[i]=z;
}
int l=0,r=n;
int ans=0;
while(l<=r){
int mid=((r+l)>>1);
if(b[mid]>k){
r=mid-1;
}else{
ans=mid;
l=mid+1;
}
}
cout<<ans<<endl;
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);cout.tie(nullptr);
int oyyo=1;
// cin>>oyyo;
while(oyyo--) {
solve();
}
return 0;
}