1001
贪心:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long LL;
#define MAXN 10005
int _,n,k;
LL num[MAXN],m;
bool solve()
{
int u = upper_bound(num,num + n,m)- num;
if(u == n)return true;
else if(m < num[0])return false;
if(num[u] > m)u--;
m = num[u];
while(u < n)
{
m += k;
if(m < num[u + 1])return false;
while(u != n && m >= num[u + 1])
u++;
if(u == n)return true;
m = num[u];
k--;
if(u != n && k == 0)return false;
}
return true;
}
int main()
{
for(int kcas = scanf("%d",&_);kcas <= _;kcas++)
{
printf("Case #%d:\n",kcas);
scanf("%d%I64d%d",&n,&m,&k);
for(int i = 0;i < n;i++)
scanf("%I64d",&num[i]);
sort(num,num + n);
if(solve())puts("why am I so diao?");
else puts("madan!");
}
}
1002
暴力枚举,巧用STL:
#include<cstdio>
#include<set>
#include<algorithm>
#include<iostream>
using namespace std;
typedef long long LL;
const int MAXN = 10005;
set<LL>se;
set<LL> :: iterator it1,it2;
int n,m;
int ans[MAXN];
LL arr[MAXN];
int main()
{
scanf("%d%d",&n,&m);
for(int i = 0;i < n;i++)
scanf("%I64d",&arr[i]);
for(int j = 0;j < n;j++)
{
se.clear();
for(int i = 0;i < 1000 && i + j < n;i++)
{
if(!se.count(arr[j + i]))
se.insert(arr[j + i]);
else
break;
int minn = *(se.begin());
int maxn = *(se.rbegin());
if(maxn - minn == se.size() - 1)
ans[i]++;
}
}
printf("Case #1:\n");
while(m--)
{
int k;
scanf("%d",&k);
printf("%d\n",ans[k - 1]);
}
return 0;
}
1003
二分枚举:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
#define MAXN 100005
int _,num[MAXN],n;
bool have(int val)
{
int u = num[0] - val,v;
//cout << val << " val " << endl;
for(int i = 1;i < n;i++)
{
if(num[i] <= u)v = min(num[i] + val,u + 1);
else if(num[i] > u)v = max(num[i] - val,u + 1);
if(v <= u)return false;
u = v;
//cout << u << " u v " << v << endl;
}
return true;
}
int solve()
{
int l = 0,r = 1e7;
while(l < r)
{
int mid = l + r >> 1;
if(have(mid))r = mid;
else l = mid + 1;
}
return l;
}
int main()
{
for(int kcas = scanf("%d",&_);kcas <= _;kcas++)
{
printf("Case #%d:\n",kcas);
scanf("%d",&n);
for(int i = 0;i < n;i++)
scanf("%d",&num[i]);
int ans = solve();
printf("%d\n",ans);
}
}
1004:
树状数组内二分求第k大
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
#define MAXN 10005
int n;
#define lowbit(i) (i & -i)
int prefix[MAXN],order[MAXN],de[MAXN],has[MAXN];
struct Discrete
{
int num,newnum,id;
char op[7];
bool operator < (const Discrete & nu)const{
return num < nu.num;
}
}d[MAXN];
void modify(int l,int r,int key)
{
for(;l <= r;l += lowbit(l))
prefix[l] += key;
}
int find_kth(int num,int n)
{
int ans = 0,LOG = 0;
while((1 << LOG) <= n)LOG++;
for(int i = LOG;i >= 0;i--)
{
int cur = 1 << i;
if(ans + cur > n || num <= prefix[ans + cur])
continue;
ans += cur;
num -= prefix[ans];
}
return ans + 1;
}
void solve()
{
int u = 0,v = 0;
for(int i = 0;i < n;i++)
{
int j = order[i];
if(d[j].op[0] == 'i')
{
de[u++] = d[j].newnum;
modify(d[j].newnum,n,1);
}
else if(d[j].op[0] == 'o')
{
modify(de[v++],n,-1);
}
else
{
int num = (u - v) / 2 + 1;
int ans = find_kth(num,n + 1);
//cout << ans << " ans " << endl;
printf("%d\n",has[ans]);
}
}
}
int main()
{
int kcas = 1;
while(scanf("%d",&n) != EOF)
{
memset(prefix,0,sizeof(prefix));
printf("Case #%d:\n",kcas++);
for(int i = 0;i < n;i++)
{
scanf("%s",d[i].op);
d[i].id = i;
if(d[i].op[0] == 'i')scanf("%d",&d[i].num);
else d[i].num = 0x3f3f3f3f;
}
sort(d,d + n);
for(int i = 0;i < n;i++)
{
order[d[i].id] = i;
//cout << d[i].id << " id " << endl;
if(d[i].num == 0x3f3f3f3f)continue;
if(i == 0)d[i].newnum = 1;
else if(d[i].num == d[i - 1].num)d[i].newnum = d[i - 1].newnum;
else d[i].newnum = d[i - 1].newnum + 1;
//cout << d[i].newnum << " new " << endl;
has[d[i].newnum] = d[i].num;
}
solve();
}
}