https://codeforces.com/contest/1561/problem/A
定义一个操作,对数列的1-n,交换num[i]和num[i+1],为f(i)为奇数时只对奇数交换,为f(i)为偶数时只对偶数交换,问你至少需要多少次操作使得数列有序。
由于数据非常的小,我们可以直接枚举f(i),直接模拟,然后对每次模拟检测一遍数列是否有序就可以了。
#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define rep(i,a,n) for (int i=a;i<=n;i++)
#define per(i,a,n) for (int i=n;i>=a;i--)
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
inline ll read()
{
ll x=0,w=1; char ch=0;ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')w=-1;ch=getchar();}
while(ch<='9'&&ch>='0'){x=(x<<3)+(x<<1)+(ch-48);ch=getchar();}
return x*w;
}
inline void print(ll x)
{
if(x<0){x=-x;putchar('-');}
if(x>9)print(x/10);
putchar(x%10+48);
}
const int N=1000;
int t,n,num[N];
int check()
{
//rep(i,1,n)cout<<num[i]<<endl;
for(int i=1;i<=n-1;i++)
{
if(num[i]>num[i+1])return 1;
}
return 0;
}
void solve()
{
memset(num,0,sizeof(num));
int k=0; n=0;
cin>>n;
rep(i,1,n)cin>>num[i];
while(check())
{
//cout<<1<<endl;
k++;
if(k%2)
{
for(int i=1;i<=n;i++)
{
if(i%2&&i!=n)
{
if(num[i]>num[i+1])swap(num[i],num[i+1]);
}
}
}
else
{
for(int i=1;i<=n;i++)
{
if(i%2==0)
{
if(num[i]>num[i+1])swap(num[i],num[i+1]);
}
}
}
}
cout<<k<<endl;
//rep(i,1,n)cout<<num[i]<<' ';cout<<endl;
}
int main()
{
ios
cin>>t;
while(t--)solve();
return 0;
}
https://codeforces.com/contest/1561/problem/C
有n个洞穴,在洞穴里有m只怪物,每只怪物有一个护甲值,如果你力量值高于护甲值你就能击杀这个怪物,每击杀一个怪物会增加一点力量值,怪物需要按顺序杀,但是你可以选择进入洞穴的顺序,问你你能够击杀所有的怪物的前提下,开始的最小力量值是多少。
我的思路是对每个洞穴最小需要的力量值进行二分答案,找到能够击败这个洞穴所有怪物的最小力量,然后对每个洞穴的力量值进行排序,再二分一次答案,找到大于等于能够击败所有洞穴怪物的力量。
复杂度nlogn+nlogn
其实并不需要这么麻烦,遇到力量值不够的情况直接把力量值提高到刚好能击败怪物就可以了。写的麻烦了码力不够,最后太困了搞错了排序之后洞穴的大小和击败这个洞穴需要的最小力量就不匹配了。还是太菜了。
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<cstdio>
#include<queue>
#include<stack>
#include<map>
#include<vector>
#define ll long long
#define ull unsigned long long
#define rep(i,a,n) for (int i=a;i<=n;i++)
#define per(i,a,n) for (int i=n;i>=a;i--)
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
inline ll read()
{
ll x=0,w=1; char ch=0;ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')w=-1;ch=getchar();}
while(ch<='9'&&ch>='0'){x=(x<<3)+(x<<1)+(ch-48);ch=getchar();}
return x*w;
}
inline void print(ll x)
{
if(x<0){x=-x;putchar('-');}
if(x>9)print(x/10);
putchar(x%10+48);
}
bool cmp(pair<int,int> a,pair<int,int> b)
{
return a.second<b.second;
}
const int N=1e5+5;
int t,n,s;
pair<int,int> power[N];
vector<int> cave[N];
int tmp;
int check(int a,int x)
{
for(int i=0;i<cave[x].size();i++)//写成cave[i].size..粗心啊
{
if(a>cave[x][i])a++;
else return 0;
//cout<<a<<'---';
}
return 1;
}
int checks(int a)
{
for(int i=1;i<=n;i++)
{
if(a > power[i].second)//排序之后cave【i】和power【i】就对不上了..
{
a+=power[i].first;
//cout<<'a'<<a<<endl;
}
else return 1;
}
return 0;
}
void solve()
{
cin>>n;
rep(i,1,n)
{
cave[i].clear();
}
rep(i,1,n)
{
cin>>s;
rep(j,1,s)
{
cin>>tmp;
cave[i].push_back(tmp);
}
//一定要按顺序打,这里不能排序。debug
int l=1,r=1e9+5,ans=0;
while(l<=r)
{
int mid=(l+r)/2;
if(check(mid,i))
{
ans=mid;
r=mid-1;
}
else l=mid+1;
//cout<<mid<<' '<<ans<<endl;
}
power[i].first=cave[i].size();
power[i].second=ans;
}
// rep(i,1,n)
// {
// rep(j,0,cave[i].size()-1)
// {
// cout<<cave[i][j]<<' ';
// }
// cout<<endl;
// }
sort(power+1,power+n+1,cmp);//我power是从1开始的,不能从0开始排。debug1小时。
//rep(i,1,n)cout<<power[i]<<' ';cout<<endl;
int l=1,r=1e9+5,ans=0;
while(l<=r)
{
int mid=(l+r)/2;
if(checks(mid))
{
ans=mid;
l=mid+1;
}
else r=mid-1;
}
cout<<ans<<endl;
}
int main()//本想对每个洞穴里面的怪排序
{
ios
cin>>t;
while(t--)solve();
return 0;
}