CCF 刷题记录

写在前面

  1. 题目要从易到难,遇到困难试着分解思考。
  2. 算法的复杂度(尽可能)控制在 O(N^2)内。

【1】2021-09-01 数组推导(100分)

因为单调不减的特性,最大值就是直接加;最小值就是单调栈求和。

#include<iostream>
using namespace std;

int main(){
	int n , t , max_sum = 0 , min_sum = 0 , max_i = -1;
	scanf("%d" , &n);
	for(int i = 0 ; i < n ; i ++){
		scanf("%d" , &t);
		max_sum += t;
		
		if(max_i < t){
			max_i = t;
			min_sum += t;
		}
	}
	
	printf("%d\n%d" , max_sum , min_sum);
	return 0;
}

【2】2021-04-01 灰度直方图(100分)

记一下 memset 和 freopen。

#include<iostream>
#include<string.h>
using namespace std;

int main(){
	//freopen("Data.txt" , "r" , stdin);
	int n , m , l , t , h[258];
	memset(h , 0 , sizeof(h));
	scanf("%d %d %d" , &n , &m , &l);
	
	// 输入 
	for(int i = 0 ; i < n ; i ++){
		for(int j = 0 ; j < m ; j ++){
			scanf("%d" , &t);
			h[t] += 1;
		}	
	}
	
	// 输出
	for(int i = 0 ; i < l ; i ++){
		if(i == l - 1)	printf("%d" , h[i]);
		else	printf("%d " , h[i]);
	} 
	return 0;
}

【3】2021-04-02 邻域均值(70分)

考察:【差分】
思路简单清晰,但是超时了。我当时就怀疑这种方法很好使,但是就是会超时。
有个优化的思路就是,对 Calculate 函数可以做一些小的改动就会变得更好。但是暂时我想不出来。

#include<iostream>
using namespace std;

const int N = 605;
int A[N][N] , r , t , n;

bool Calculate(int i , int j){
	
	// 直接遍历循环 
	int sum = 0 , num = 0; 
	for(int a = i - r ; a <= i + r ; a ++){
		for(int b = j - r ; b <= j + r ; b ++){
			
			// 遇到边界值的时候跳过 
			if(a < 0 || a >= n || b < 0 || b >= n)	continue;
			
			// 求和并记录数据 
			sum += A[a][b]; 
			num ++;  
			
			// 加速判断
			if(sum > (2 * r + 1) * (2 * r + 1) * t)	return false; 
		}
	}
	
	// 做出判断 
	if(sum <= num * t)	return true;  // black
	else return false; 
}

int main(){
	//freopen("Data.txt" , "r" , stdin);
	int L , sum = 0;
	
	// 输入 
	scanf("%d %d %d %d" , &n , &L , &r , &t);
	for(int i = 0 ; i < n ; i ++){
		for(int j = 0 ; j < n ; j ++){
			scanf("%d" , &A[i][j]);
		} 
	}
	
	// 计算 & 统计
	for(int i = 0 ; i < n ; i ++){
		for(int j = 0 ; j < n ; j ++){
			if(Calculate(i , j) == true)	sum ++;	
		} 
	} 
	
	// output
	printf("%d" , sum); 
	return 0;
}

【4】2020-12-01 期末预测之安全指数(100分)

一个简单的求和运算。

#include<iostream>
using namespace std;

int main(){
	int n , w , score , sum = 0;
	scanf("%d" , &n);
	for(int i = 0 ; i < n ; i ++){
		scanf("%d %d" , &w , &score);
		sum += w * score;
	}
	int y = max(sum , 0);
	printf("%d" , y);
	return 0;
} 

 

【5】2020-12-02 期末预测之最佳阈值 (第一版:40分,第二版:100分)

40分的代码,不知道为什么只能拿到40分。首先一个感觉是这个循环可能有问题,时间复杂度有点高了;其他的暂时不明白。随后看看有没有什么高人给解释一下。

#include<iostream>
using namespace std;

int main(){
	//freopen("Data.txt","r",stdin);
	int m , max_theta = 0 , max_n = -1;
	int w[100005] , result[100005];
	
	//输入 
	scanf("%d" , &m);
	for(int i = 0; i < m; i ++){
		scanf("%d %d", &w[i] , &result[i]);
	}
	
	//如果成绩比pre要 ≥的都为及格1;成绩比pre低的要为 0 
	for(int i = 0 ; i < m ; i ++){
		int pre = w[i] , n = 0;	//n代表判断对的个数 
		for(int j = 0 ; j < m ; j ++){
			if((pre <= w[j] && result[j] == 1) || (pre > w[j] && result[j] == 0))
				n ++; 
		}
		if(n >= max_n && pre >= max_theta){
			max_n = n;
			max_theta = pre;
		} 
	} 
	printf("%d" , max_theta);
	return 0;
}

第二版:时间复杂度从On2降为了On。

#include<iostream>
#include<set>
#include<algorithm>
#include<map>
using namespace std;

set<int> s;
map<int , int> Mzero;
map<int , int> Mone;

int main(){
	int m;
	int zero = 0 , one = 0;
	//freopen("Data.txt" , "r" , stdin);
	
	//input
	scanf("%d" , &m);
	for(int i = 0 ; i < m ; i ++){
		int y , result;
		scanf("%d %d" , &y , &result);
		
		// 将所有的阈值都输入进来,从小到大做一个排序 
		s.insert(y);
		
		//统计一下里面有多少个 0 和 1  
		if(result == 1)	Mone[y] ++ , one ++;
		else Mzero[y] ++ , zero ++;
		
	}
	
	// Find max 
	int Max = -1 , now_one = 0 , before_zero = zero , max_theta = -1;
	for(set<int>:: iterator it = (--s.end()) ; it != (--s.begin()) ; it --){
		
		now_one += Mone[*it];
		before_zero -= Mzero[*it];
		int max_i = now_one + before_zero;
		
		// judge
		if(max_i > Max){
			Max = max_i;
			if(max_theta == -1)	max_theta = *it;
			else if(max_theta > *it && max_theta != -1) max_theta = *it;
		} 
	}
	
	// output
	printf("%d" , max_theta); 
	return 0;
} 

 

【6】2020-09-01 称检测点查询 (100分)

pair的用法,可以结合sort使用。

#include<iostream>
#include<algorithm>
using namespace std;

int main(){
	//freopen("Data.txt","r",stdin);
	int n , x , y;
	pair<int , int> p[205];
	scanf("%d %d %d" , &n , &x , &y);
	
	for(int i = 1 ; i <= n ; i ++){
		int a , b;
		scanf("%d %d" , &a , &b);
		int dis = (x - a)*(x - a) + (y - b)*(y - b);
		p[i] = {dis , i};
	}
	
	sort(p , p + n);	//对p从小到大排序 
	
	for(int i = 1 ; i <= 3 ; i ++){
		printf("%d\n" , p[i].second);	
	} 
	return 0;
} 

 

【7】2020-09-02 风险人群筛查 (100分)

主要考察的就是 flag 设计。

#include<iostream>
using namespace std;

int main(){
	int n , k , t , xl , yd , xr , yu;
	int bdfn = 0 , idfn = 0;	// 经过人数,逗留人数 
//	freopen("data.txt" , "r" , stdin);
	
	scanf("%d %d %d %d %d %d %d" , &n , &k , &t , &xl , &yd , &xr , &yu);
	
	// 输入 
	for(int i = 1 ; i <= n ; i ++){
		
		int num_k = 0;
		bool is_dangerous = false , flag = false , dangerous = false; 
		for(int j = 1 ; j <= t ; j ++){
			
			int x , y;
			scanf("%d %d" , &x , &y);
			
			//进入过 
			if((xl <= x && x <= xr) && (yd <= y && y <= yu))	
				is_dangerous = true , flag = true;
			else 
				flag = false , num_k = 0; 
			
			//逗留
			if(is_dangerous == true && flag == true){
				num_k ++;
				if(num_k >= k)	dangerous = true;	
			}
		} 
		
		// 统计个数
		if(is_dangerous == true)	bdfn ++;
		if(dangerous == true)	idfn ++; 
	} 
	
	// 输出
	printf("%d\n%d" , bdfn , idfn); 
	return 0;
} 

 

【8】2020-06-01 线性分类器 (100分)

思路

  1. 难点在于判断上。因为不知道上下哪个部分为A,哪个为B,故假设线性分类器上半部分为A,下半部分为B。统计点的数量。如果正确的话,这个点的数量要么是=n(如假设一致)要么等于0(如假设相反)。
  2. 双循环内部,j 和 i 不要写错了。否则很难查出错误。
#include<iostream>
using namespace std;

struct node{
	int x , y;
	char type;
}Node[100005];


//Function :Check 
bool Check(int n , int t1 , int t2 , int t3){
	int st = 0;//用于统计的量st 
	for(int i = 0 ; i < n ; i ++){
		int key = t1 + Node[i].x * t2 + Node[i].y * t3;
		
		//假设上半部分的数值为A,下半部分的数值为B。每个点带入,进行统计 
		//那么最终的答案要么是0(和上面完全相反),要么答案是n完全满足上方假设
		if((key > 0 && Node[i].type == 'A') || (key < 0 && Node[i].type == 'B'))	st ++;	 
	}
	if(st == 0 || st == n)	return true;
	else return false;
}

int main(){
	int n , m;
	freopen("Data.txt" , "r" , stdin);
	scanf("%d %d" , &n , &m);
	
	for(int i = 0 ; i < n ; i ++){
		cin >> Node[i].x >> Node[i].y >> Node[i].type;
	}
	
	for(int i = 0 ; i < m ; i ++){
		int theta1 , theta2 , theta3;
		cin >> theta1 >> theta2 >> theta3;
		
		bool ans = Check(n , theta1 , theta2 , theta3);
		
		if(ans == 1)	cout << "Yes" << endl;
		else	cout << "No" << endl;	
	}
	return 0;
} 

 

【9】2020-06-02 稀疏向量 (100分)

要点

  1. 我本来觉得这个题目开一个数组,因为太浪费空间了,所以选择用了一个 map。(map支持long long)
  2. 主体思路就是,将第一次的存好,第二次的如果一致就修改数据之后直接求和,不需要再开一个 for 循环等着求和了,那样会将第一次求和的都算进来。也不用 iterator 了直接求和就行。
  3. 当数字出现乘法的时候,要考虑是否会出现 int 不够的情况。需要用 long long(10的10次~18次,%lld )。
  4. map 可以直接赋值;map 的 find 函数和判断是重点,一定要会用。
#include<iostream>
#include<map>
using namespace std;

int main(){
	int n , a , b , x;
	long long y , sum = 0;
	map<int , long long> mp;//直接用数组存也是可以的,但是那样数据太大了。 
	
	//freopen("Data.txt" , "r" , stdin); 
	scanf("%d %d %d" , &n , &a , &b);
	for(int i = 0 ; i < a ; i ++){		
		scanf("%d %lld" , &x , &y);
		
		//因为这是第一次,所以可以直接赋值
		mp[x] = y;	
	} 
	
	for(int i = 0 ; i < b ; i ++){		
		scanf("%d %lld" , &x , &y);
		
		//这是第二次的,因为这个map有值,则直接乘进去;没值就不用管了,反正内交一下也是0 
		if(mp.find(x) != mp.end())	mp[x] *= y;

		//也不用遍历了,直接在这里求和
		sum += mp[x];
		
	}
	
	//输出 
	cout << sum;
	return 0;
}

【10】2019-12-01 报数(100分)

要点

  1. 注意这个输出。它是1,2,3,0这个顺序。
  2. 整体思路并不复杂,忘了审题了。7的倍数且要含有7。要有抽象的思维,把判断的函数抽出来,写出框架后再去判断。
#include<iostream>
using namespace std;

//Check function
bool Check(int i){
	
	//若为7的倍数 
	if(i % 7 == 0)	return true;
	
	//若其中含有 7
	while(i > 0){
		if(i % 10 == 7)	return true;
		i /= 10;
	} 
	return false;
}

int main(){
	int n , st[5] = {0} , i = 1 , num = 0;
	cin >> n;
	
	while(1){
		
		//统计数字 
		if(Check(i) == true)	st[i % 4] ++ ;
		else	 num ++;
		
		//i也累加 
		i ++;
		
		//跳出 
		if(num == n)	break;
	} 
	
	//输出 
	for(int i = 1 ; i <= 3 ; i ++)
		cout << st[i] << endl;
	cout << st[0] << endl;
	return 0;
} 

【11】2019-12-02 回收站选址(100分)

要点
不要试图将数据存入二维数组中,直接拿出来遍历循环即可。

#include<iostream>
using namespace std;

void stat_number(int x[] , int y[] , int n){
	int stat[5] = {0};
	
	// 寻找数据 
	for(int i = 1 ; i <= n ; i ++){
		int v_num = 0 , c_num = 0;
		for(int j = 1 ; j <= n ; j ++){
			if((x[j] + 1 == x[i] && y[j] == y[i]) || (x[j] - 1 == x[i] && y[j] == y[i]) || (x[j] == x[i] && y[j] + 1 == y[i]) || (x[j] == x[i] && y[j] - 1 == y[i]))	v_num ++; // 统计四边的个数
			if((x[j] + 1 == x[i] && y[j] + 1 == y[i]) || (x[j] - 1 == x[i] && y[j] + 1 == y[i]) || (x[j] - 1 == x[i] && y[j] - 1 == y[i]) || (x[j] + 1 == x[i] && y[j] - 1 == y[i]))  	c_num ++; // 统计四角的个数			 
		}
		if(v_num == 4)	stat[c_num] ++; // 满足的数据做统计
	}
	
	// 输出
	printf("%d\n%d\n%d\n%d\n%d" , stat[0] , stat[1] , stat[2] , stat[3] , stat[4]); 
} 

int main(){
	int n , x[1005] , y[1005];
	
	// 输入 
	//freopen("data.txt" , "r" , stdin); 
	scanf("%d" , &n);
	for(int i = 1 ; i <= n ; i ++){
		scanf("%d %d" , &x[i] , &y[i]);
	} 
	
	// 做统计 
	stat_number(x , y , n);
	
	return 0;
} 

【12】2019-09-01 小明种苹果(100分)

要点

  1. 最后的逻辑判断把我卡住了,一时半会儿居然没写出来,最后捋清楚思路重写了才写出来。
  2. 最后整理一下最后的那个思路:如果说两个数一致,且该数比最小的数要大,则不动;否则则赋值。
#include<iostream>
using namespace std;

int main(){
	int N , M , min_i = 1005 , max_down_number = 0 , sum_number = 0;
	int record[1005] = {0} , apple[1005] = {0};  
	
	// 输入 
	// freopen("Data.txt" , "r" , stdin);
	scanf("%d %d" , &N , &M);
	for(int i = 1 ; i <= N ; i ++){
		
		// apple_number 记录了这个苹果树一开始的数量, down_number 记录了苹果树落下的个数; 
		int apple_number = 0 , d , down_number = 0;
		
		for(int j = 0 ; j <= M ; j ++){
			scanf("%d" , &d);
			if(j == 0)	apple_number = d;
			else	down_number += d;
		}
		
		// 计算最终的苹果数量;并做出统计 
		apple_number += down_number; 
		sum_number += apple_number;
		
		// 做出判断,这里记得 down_number 都是负数 
		if(down_number <= max_down_number){
			if(down_number == max_down_number && i >= min_i)	;//什么都不做
			else	min_i = i;

			max_down_number = down_number;	
			
		} 
	}
	
	// 输出 
	printf("%d %d %d" , sum_number , min_i , -1 * max_down_number); 
	return 0;
} 

【13】2019-09-02 小明种苹果(续)(100分)

要点

  1. 重点是:看清楚让求得是啥。
  2. scanf 这个地方也值得记一下。
#include<iostream>
using namespace std;

// 利用 bool 数组和取模求三个连续的数 
int tcn(bool drop[] , int n){
	int drop_tree_number = 0;
	for(int i = 0 ; i < n ; i ++){
		if(drop[i % n] == true && drop[(i + 1) % n] == true && drop[(i + 2) % n] == true){
			drop_tree_number ++;
		}	
	}
	return drop_tree_number; 
}

int main(){
	int n , m , drop_apple_number = 0 , sum_apple_number = 0;
	bool is_apple_drop[1005] = {false};
	
	// 输入 
	//freopen("Data.txt" , "r" , stdin);
	scanf("%d" , &n);
	for(int i = 0 ; i < n ; i ++){
		
		int a , a_sum = 0;
		
		scanf("%d" , &m);
		for(int j = 1 ; j <= m ; j ++){
			int apple;
			scanf("%d" , &apple);
			
			// 第一个数是最开始的苹果个数 
			if(j == 1)	a_sum = apple;
			
			// 中间间断的苹果个数 
			if(apple > 0)	a = apple;	
			else{
				a += apple;
				a_sum += apple;	
			}	
		}
		
		// 统计剩下的苹果总数
		sum_apple_number += a;
		
		// 判断是否有苹果掉落 
		if(a_sum - a){
			drop_apple_number ++; 
			is_apple_drop[i] = true;
		}
	} 
	
	// 计算连续掉落的苹果树的个数 
	int three_con_number = tcn(is_apple_drop , n); 
	
	// 输出 
	printf("%d %d %d" , sum_apple_number , drop_apple_number , three_con_number);
	return 0;
} 

【14】2019-03-01 小中大(100分)

要点
重点是输出的地方的操作,需要按照需求做出输出。

#include<iostream>
using namespace std;

int main(){
	int n , max_n , min_n , a , mid_n = 0;
	bool dou = false;
	//freopen("Data.txt" , "r" , stdin);
	scanf("%d" , &n);
	
	// 判断 n 是否是偶数 
	if(n % 2 == 0)	dou = true;
	
	for(int i = 1 ; i <= n ; i ++){
		scanf("%d" , &a);
		
		// 记录
		if(i == 1)	max_n = a;
		if(i == n)	min_n = a;
		
		// 如果是数据是偶数的话,中位数先加起来,先不要判断 
		
		if(dou == true){
			if(i == n / 2 || i == (n / 2 + 1))	mid_n += a;
			
		}
		else
			if(i == n / 2 + 1)	mid_n = a; 
		
	}
	
	// 判断 , 最大值和最小值 
	if(min_n > max_n){
		a = min_n;
		min_n = max_n;
		max_n = a; 
	}
	
	
	// 判断 mid 是否可以整除 2,不能整除要保留1位小数,从大到小输出 
	if(dou == true){
		if(mid_n % 2 == 0)
			printf("%d %d %d" , max_n , mid_n / 2, min_n);
		else
			printf("%d %.1f %d" , max_n , float(mid_n) / 2 , min_n);
	}
	else
		printf("%d %d %d" , max_n , mid_n , min_n);
			
	return 0;
}

【15】2018-12-01 小明上学(100分)

要点
无,简单题。

#include<iostream>
using namespace std;

int main(){
	int r , y , g , n , sum_t = 0;
	
	// freopen("Data.txt" , "r" , stdin);
	
	scanf("%d %d %d" , &r , &y , &g);
	scanf("%d" , &n);
	for(int i = 0 ; i < n ; i ++){
		int k , t;
		scanf("%d %d" , &k , &t);
		
		
		if(k == 0){
			sum_t += t;
		}	
		else if(k == 1){
			// if light is red
			sum_t += t;	
		}
		else if(k == 2){
			// if light is yellow
			sum_t += t + r;
		}
	}
	
	// output
	printf("%d" , sum_t); 
	
	return 0;
} 

【16】2018-12-02 小明放学(60分)

注意

  1. freopen 打开位置的必须和 cpp 文件保持一致。
  2. 60 分的原因没有找到,有的说是 long long 的问题,有的其他问题考虑的不全,我也不太清楚具体的原因是什么。
#include<iostream>
using namespace std;

int get_sum(int r , int y , int g , int k , int t , int sum){
	
	// 如果是路的话
	if(k == 0)	return t;
	else if(k == 1){
		// 当前是红色,计算当前所花费的时间,判断当前的灯应该是什么
		int now = (r - t + sum) % (r + g + y);
		
		// 判断当前时间是哪个节点:红色,绿色,黄色 
		if(now <= r)	return (r - now);
		if(now > r && now <= r + g)	return 0;
		if(now > r + g && now <= r + g + y)	return (r + g + y - now + r); 
	} 
	else if(k == 2){
		// 当前是黄色灯
		int now = (r + g + y - t + sum) % (r + g + y);
		
		// 判断当前时间是哪个节点:红色,绿色,黄色 
		if(now <= r)	return (r - now);
		if(now > r && now <= r + g)	return 0;
		if(now > r + g && now <= r + g + y)	return (r + g + y - now + r);
	}
	else if(k == 3){
		//当前是绿色灯
		int now = (r + g - t + sum) % (r + g + y);
		
		//判断
		if(now <= r)	return (r - now);
		if(now > r && now <= r + g)	return 0;
		if(now > r + g && now <= r + g + y)	return (r + g + y - now + r); 
	}
	
}

int main(){
	int r , y , g , n , sum = 0;
	// freopen("Data.txt" , "r" , stdin);
	
	// input 
	scanf("%d %d %d" , &r , &y , &g);
	scanf("%d" , &n);
	for(int i = 0 ; i < n ; i ++){
		int k , t;
		scanf("%d %d" , &k , &t);
		
		// 计算每一步需要的时间 
		int gt = get_sum(r , y , g , k , t , sum);
		sum += gt;
	}
	
	// 输出 
	printf("%d" , sum);
	return 0;
}

【17】2018-09-01 卖菜(100分)

注意这个地方需要重新开一个数组b。

#include<iostream>
using namespace std;

int main(){
	
	int n , a[1005] , b[1005];
	// freopen("Data.txt" , "r" , stdin);
	
	// 输入 
	scanf("%d" , &n);
	for(int i = 1 ; i <= n ; i ++){
		scanf("%d" , &a[i]);
	}
	
	// 调整 
	for(int i = 1 ; i <= n ; i ++){
		
		//针对头尾调整
		if(i == 1)	b[i] = (a[i] + a[i + 1]) / 2;
		else if(i == n)	b[i] = (a[i] + a[i - 1]) / 2;
		else	b[i] = (a[i - 1] + a[i] + a[i + 1]) / 3;
	} 
	
	//输出
	for(int i = 1 ; i <= n ; i ++){
		if(i == n)	printf("%d" , b[i]);
		else printf("%d " , b[i]);
	} 
	
	return 0;
}

【18】2018-09-02 买菜(100分)

注意:不难,画个图就看明白了。开一个大数组,然后往里填数数数就可以。

#include<iostream>
using namespace std;

int time[1000005] = {0};

int main(){
	int n;
	//freopen("Data.txt" ,"r" , stdin);
	
	scanf("%d" , &n);
	for(int i = 0 ; i < n ; i ++){
		int a , b;
		scanf("%d %d" , &a ,&b);
		
		// 将H标记好的数据放进去 
		for(int j = a ; j < b ; j ++){
			time[j] = 1;
		}
	}
	
	// 设计一个求和 sum 
	int sum = 0;
	
	for(int i = 0 ; i < n ; i ++){
		int a , b;
		scanf("%d %d" , &a , &b);
		
		// 在小 W 的时间段内,小H也有数据做过标记,则直接 sum ++; 
		for(int j = a ; j < b ; j ++){
			if(time[j] == 1)	sum ++;	
		} 
	} 
	
	printf("%d" , sum);
	return 0;
}

【19】2018-03-01 跳一跳(100分)

做好标记。

#include<iostream>
using namespace std;

int time[1000005] = {0};

int main(){
	int n ;
	long long sum = 0;
	int cont = 1;	// 连续标记 
	//	freopen("Data.txt" ,"r" , stdin);
	
	while(scanf("%d" , &n) == 1){
		if(n == 1)	{
			sum += 1;
			cont = 1;	
		}
		else if(n == 2){
			sum += 2 * cont; // 对于连续的做出统计,做和 
			cont ++;
		}
		else if(n == 0)	break;	// 退出	
	}
	
	printf("%lld" , sum); 
	
	return 0;
}

【20】2018-03-02 碰撞的小球

没做完。

#include<iostream>
using namespace std;

int ball[105];

int main(){
	int n , L , t;
	scanf("%d %d %d" , &n , &L , &t);
	for(int i = 1 ; i <= n ; i ++){
		scanf("%d" , &ball[i]);
	}
	 
	
	// 移动球 
	for(int i = 1 ; i <= t ; i ++){
		for(int j = n ; j >= 1 ; j --){
			if(ball[j] < L)	ball[j] += 1;
			else if(ball[j] >= L){
				ball[j] -= 1;
				L = ball[j];
			}
				
		}
		for(int j = 1 ; j <= n ; j ++){
			printf("%d " , ball[j]);
		}
		printf("\n");
	}
	
	// output 
	for(int i = 1 ; i <= n ; i ++){
		if(i == n)	printf("%d" , ball[i]);
		else printf("%d " , ball[i]);
	}
	return 0;
}

【21】2016-12-01 中间数(100分)

注意

  1. 复习一下 sort 的用法
  2. 不用开两个指针,只要总数 - 前面 - 中间重复数字就可以。
#include<iostream>
#include<algorithm>
using namespace std;

bool cmp(int a , int b){
	return a < b;
}

int main(){
	int n , a , num[1005], stat[1005] = { 0 } , state_num = 0 , j = 0;
	//freopen("Data.txt" , "r" , stdin);
	
	scanf("%d" , &n);
	for(int i = 0 ; i < n ; i ++){
		scanf("%d" , &a);
		stat[a] += 1;
		if(stat[a] <= 1){
			num[j ++] = a ; 
			state_num ++;
		}	 
	}
	
	// 对数组排序 
	sort(num , num + state_num , cmp);
	
	// output
	for(int i = 0 ; i < state_num ; i ++){
		int sum = 0;
		for(int j = 0 ; j < i ; j ++){
			if(num[j] < num[i])	sum += stat[num[j]];
			else break; 
		}
		
		//判断中间数是否存在
		if(sum == n - sum - stat[num[i]]){
			printf("%d" , num[i]);	
			return 0;
		} 
	} 
	printf("-1");
	return 0;
} 
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值