2017暑期ACM俱乐部个人训练赛第2场
G:3425: Balanced Photo
时间限制: 1 Sec 内存限制: 128 MB提交: 107 解决: 44
[ 提交][ 状态][ 讨论版]
题目描述
Farmer John is arranging his N cows in a line to take a photo (1≤N≤100,000). The height of the ith cow in sequence ishi, and the heights of all cows are distinct.
As with all photographs of his cows, FJ wants this one to come out looking as nice as possible. He decides that cow i looks "unbalanced" if Li and Ri differ by more than factor of 2, where Li and Ri are the number of cows taller than i on her left and right, respectively. That is, i is unbalanced if the larger of Li and Ri is strictly more than twice the smaller of these two numbers. FJ is hoping that not too many of his cows are unbalanced.
Please help FJ compute the total number of unbalanced cows.
输入
输出
样例输入
7
34
6
23
0
5
99
2
样例输出
3
提示
In this example, the cows of heights 34, 5, and 2 are unbalanced.
刚学树状数组,看了个大神的博客
ac代码#include <stdio.h>
#include <cmath>
#include <cstring>
#include <queue>
#include <algorithm>
#define ll long long
using namespace std;
const int maxn=100000+5;
struct node{
int val,index;
}nn[maxn];
int n;
int tree[maxn];
int tmp[maxn];
int le[maxn],ri[maxn];
bool cmp(node x,node y){
return x.val < y.val;
}
void add(int k,int num){
while(k <= n){
tree[k]+=num;
k+=k&-k;
}
}
int read(int k){
int sum=0;
while(k > 0){
sum+=tree[k];
k-=k&-k;
//printf("tttttttt\n");
}
return sum;
}
int main()
{
while(~scanf("%d",&n)){
//printf("n==%d\n",n);
for(int i=1;i<=n;i++){
scanf("%d",&nn[i].val);
nn[i].index=i;
}
sort(nn+1,nn+n+1,cmp);
//memset(tmp,-1,sizeof(tmp));
for(int i=1;i<=n;i++){
tmp[nn[i].index]=i;
}
memset(tree,0,sizeof(tree));
for(int i=1;i<=n;i++){
// printf("******i==%d*******\n",i);
add(tmp[i],1);
le[i]=i-read(tmp[i]);
}
//printf("ni zou a\n");
memset(tree,0,sizeof(tree));
for(int i=n;i>=1;i--){
add(tmp[i],1);
ri[i]=n-i+1-read(tmp[i]);
}
int ans=0;
for(int i=1;i<=n;i++){
if(max(le[i],ri[i]) > min(le[i],ri[i])*2){
ans++;
}
}
printf("%d\n",ans);
}
return 0;
}
问题 J: 【搜索】桐桐的组合
时间限制: 1 Sec 内存限制: 64 MB提交: 260 解决: 78
[ 提交][ 状态][ 讨论版]
题目描述
排列与组合是常用的数学方法,桐桐刚刚学会了全排列,就想试试组合,组合就是从n个元素中抽出r个元素(不分顺序且r≤n),我们可以简单地将n个元素理解为自然数1,2,…,n,从中任取r个数。
输入
两个整数n和r(1≤r≤n≤20)。
输出
输出所有的组合,每一个组合占一行且其中的元素按由小到大的顺序排列,每个元素占三个字符的位置,所有的组合也按字典顺序。
样例输入
5 3
样例输出
1 2 3
1 2 4
1 2 5
1 3 4
1 3 5
1 4 5
2 3 4
2 3 5
2 4 5
3 4 5
提示
ac代码:#include <stdio.h>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;
int n,r;
int vis[50];
int ans[5];
void dfs(int d){
for(int i=ans[d-1]+1;i<=n;i++){
if(!vis[i]){
ans[d]=i;
vis[i]=1;
if(d==r){
//printf("%d",ans[1]);
for(int j=1;j<=r;j++){
printf("%3d",ans[j]);
}
printf("\n");
}
else
dfs(d+1);
vis[i]=0;
}
}
}
int main()
{
while(~scanf("%d%d",&n,&r)){
memset(vis,0,sizeof(vis));
ans[0]=0;
dfs(1);
}
return 0;
}