2017暑期ACM俱乐部个人训练赛第2场

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 (1N100,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.

输入

The first line of input contains  N . The next  N  lines contain  h1hN , each a nonnegative integer at most 1,000,000,000.

输出

Please output a count of the number of cows that are unbalanced.

样例输入

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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值