设n个数被分成了两组,一组k个数,另一组n-k个数
假设这k个数的平均值是数组的平均值average,那么另一组n-k个数的平均值也必定为average
证明:
假设n-k个数的平均值不是average, 由于在n-k个数的平均值等于average时,我们可以很容易的算出这个数组的平均值是,average,若这n-k个数组的平均值 > average,我们用这个数组和n个数的数组合一起算出来的平均值是大于average的
所以,只要我们确定了k个数的平均值是average,剩下n-k个数的平均值也必定是average,因此就转换成了01背包问题,并且我们会划分成两个子集,那么肯定有一个子集中元素的个数 <= n/2
//手写堆超时,37/51
struct Node{
int num,pos; //记录每个点的值和在数组中的下标
}heap[100010];
int cnt; //堆的大小
void down(int x)
{
int tt = x;
if(2*x <= cnt && heap[tt].num < heap[2*x].num) tt = 2 * x;
if(2*x+1<=cnt && heap[tt].num < heap[2*x+1].num) tt = 2 * x + 1;
if(tt != x)
{
int temp_num = heap[tt].num, temp_pos = heap[tt].pos;
heap[tt].num = heap[x].num;
heap[tt].pos = heap[x].pos;
heap[x].num = temp_num;
heap[x].pos = temp_pos;
down(tt);
}
}
int* maxSlidingWindow(int* nums, int n, int k, int* returnSize){
int* res = malloc(sizeof(int)*n);
int len = 0;
cnt = 0;
for(int i = 0; i < k; i++){
heap[++cnt].num = nums[i];
heap[cnt].pos = i;
}
for(int i = cnt/2;i;i--) down(i);
res[len++] = heap[1].num;
for(int i = k; i < n; i++){
int start = i - k + 1;
heap[++cnt].num = nums[i];
heap[cnt].pos = i;
for(int z = cnt; z; z--) down(z);
while(heap[1].pos < start)
{
heap[1].num = heap[cnt].num;
heap[1].pos = heap[cnt].pos;
for(int z = cnt;z;z--) down(z);
}
res[len++] = heap[1].num;
}
*returnSize = len;
return res;
}
#include
#include
#include
#define N (int)(1e6+10)
int n,k;
int q[N],nums[N];
int main()
{
scanf("%d%d",&n,&k);
for(int i = 0; i < n; i++) scanf("%d",&nums[i]);
int front = 0, tail = -1; //注意队列queue中记录的是下表,并且是窗口内的下标
//我们始终保持队头元素是答案,求最大值就是单调递减的队列,求最小值就是单调递增的队列
for(int i = 0; i < n; i++){
int start = i - k + 1;
while(front <= tail && q[front] < start) front++;
while(front <= tail && nums[q[tail]] > nums[i]) tail--;
q[++tail] = i;
if(start >= 0) printf("%d ",nums[q[front]]);
}
printf("\n");
front = 0, tail = -1;
for(int i = 0; i < n; i++){
int start = i - k + 1;
while(front <= tail && q[front] < start) front++; //如果有元素不在窗口内就弹出
while(front <= tail && nums[q[tail]] < nums[i]) tail--; //那些比这个数更小的数都不可能被使用了
q[++tail] = i;
if(start >= 0) printf("%d ",nums[q[front]]);
}
return 0;
}
struct Node{
int num,val; //数字和数字出现的次数
}nodes[100010];
int cmp(const void* a,const void* b) //数组从小到大排序
{
return *(int*)a - *(int*)b;
}
int cmp2(const void* a,const void* b) //结果结构体从大到小排序
{
struct Node* aa = (struct Node*)a;
struct Node* bb = (struct Node*)b;
if(aa->val < bb->val) return 1;
return -1;
}
int* topKFrequent(int* nums, int numsSize, int k, int* returnSize){
*returnSize = k;
int n = numsSize;
int* res = malloc(sizeof(int)*n);
qsort(nums,n,sizeof(nums[0]),cmp);
int cnt = 0;
nodes[cnt].num = nums[0];
nodes[cnt].val = 1;
for(int i = 1; i < n; i++){
if(nums[i] == nums[i-1]){
nodes[cnt].val++;
}
else{
nodes[++cnt].num = nums[i];
nodes[cnt].val = 1;
}
}
qsort(nodes,cnt+1,sizeof(nodes[0]),cmp2);
for(int i = 0; i < k; i++) res[i] = nodes[i].num;
return res;
}
注意这个题是得能够停在这个点,不仅仅是能够经过这个点就可以的
struct Node{
int x,y;
};
int dx[4] = {1,-1,0,0},dy[4] = {0,0,1,-1};
bool hasPath(int** maze, int mazeSize, int* mazeColSize, int* start, int startSize, int* destination, int destinationSize){
int n = mazeSize, m = *mazeColSize;
bool visit[1010][1010];
memset(visit,0,sizeof(visit));
struct Node queue[10010];
memset(queue,0,sizeof(queue));
int front = 0 ,tail = -1;
queue[++tail].x = start[0];
queue[tail].y = start[1];
visit[start[0]][start[1]] = true;
while(front <= tail)//队列记录那些被访问过墙边界上的节点
{
struct Node node = queue[front++];
if(node.x == destination[0] && node.y == destination[1]) return true;
for(int i = 0; i < 4; i++)
{
int nx = node.x + dx[i];
int ny = node.y + dy[i];
while(nx >= 0 && nx < n && ny >= 0 && ny < m && maze[nx][ny] != 1)
{
nx += dx[i],ny += dy[i];
}
nx -= dx[i], ny -= dy[i];
if(!visit[nx][ny]){
visit[nx][ny] = true;
tail++;
queue[tail].x = nx;
queue[tail].y = ny;
}
}
}
if(visit[destination[0]][destination[1]]) return true;
return false;
}
struct Node{
int x,y;
};
int dx[4] = {0,0,1,-1};
int dy[4] = {1,-1,0,0};
int shortestDistance(int** maze, int mazeSize, int* mazeColSize, int* start, int startSize, int* destination, int destinationSize){
int n = mazeSize, m = *mazeColSize;
int dis[n+10][m+10];
memset(dis,0x3f,sizeof(dis));
dis[start[0]][start[1]] = 0;
struct Node queue[10010];
int front = 0, tail = -1;
queue[++tail].x = start[0];
queue[tail].y = start[1];
while(front <= tail)
{
struct Node node = queue[front++];
for(int i = 0; i < 4; i++)
{
int nx = node.x + dx[i];
int ny = node.y + dy[i];
int step = 1;
while(nx >= 0 && nx < n && ny >= 0 && ny < m && maze[nx][ny] != 1){
nx = nx + dx[i],ny = ny + dy[i];
step++;
}
nx -= dx[i], ny -= dy[i], step--;
if(dis[nx][ny] > dis[node.x][node.y] + step){
dis[nx][ny] = dis[node.x][node.y] + step;
queue[++tail].x = nx;
queue[tail].y = ny;
}
while(nx != node.x && ny != node.y){
dis[nx][ny] = fmin(dis[nx][ny],dis[node.x][node.y]+step);
nx -= dx[i],ny -= dy[i];
step--;
}
}
}
if(dis[destination[0]][destination[1]] > 0x3f3f3f3f/2) return -1;
return dis[destination[0]][destination[1]];
}
struct Node{
int x,y;
};
int visit[110][110];
int dx[4] = {1,-1,0,0},dy[4] = {0,0,1,-1};
int nearestExit(char** maze, int mazeSize, int* mazeColSize, int* entrance, int entranceSize){
int n = mazeSize, m = *mazeColSize;
int dis[110][110];
memset(visit,0,sizeof(visit));
memset(dis,0x3f,sizeof(dis));
dis[entrance[0]][entrance[1]] = 0;
struct Node queue[10010];
int front = 0, tail = -1;
queue[++tail].x = entrance[0];
queue[tail].y = entrance[1];
while(front <= tail)
{
struct Node node = queue[front++];
for(int i = 0; i < 4; i++){
int nx = node.x + dx[i];
int ny = node.y + dy[i];
if(nx < 0 || nx >= n | ny < 0 || ny >= m || maze[nx][ny] == '+' ||visit[nx][ny]) continue;
dis[nx][ny] = dis[node.x][node.y] + 1;
visit[nx][ny] = true;
queue[++tail].x = nx;
queue[tail].y = ny;
}
}
int res = 0x3f3f3f3f;
for(int i = 0; i < n; i++){
int x = i, y = 0;
if(x == entrance[0] && y == entrance[1]) continue;
res = fmin(res,dis[x][y]);
}
for(int i = 0; i < m; i++)
{
int x = 0, y = i;
if(x == entrance[0] && y == entrance[1]) continue;
res = fmin(res,dis[x][y]);
}
for(int i = 0; i < n; i++){
int x = i, y = m-1;
if(x == entrance[0] && y == entrance[1]) continue;
res = fmin(res,dis[x][y]);
}
for(int i = 0; i < m; i++){
int x = n-1,y = i;
if(x == entrance[0] && y == entrance[1]) continue;
res = fmin(res,dis[x][y]);
}
if(res > 0x3f3f3f3f / 2) return -1;
return res;
}
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
void reverse(char* s)
{
int n = strlen(s);
int l = 0, r = n - 1;
while(l < r)
{
char temp = s[l];
s[l] = s[r];
s[r] = temp;
l++,r--;
}
}
char hash[26] = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
struct Node{
char tmp[10010];
}nodes[10010];
int pos;
int cmp(const void* a, const void* b)
{
struct Node* aa = (struct Node*)a;
struct Node* bb = (struct Node*)b;
if(strcmp(aa->tmp,bb->tmp) > 0) return 1;
return -1;
}
void dfs(struct TreeNode* root,char* path,int cnt)
{
if(root->left == NULL && root->right == NULL)
{
path[cnt++] = hash[root->val];
for(int i = 0; i < cnt; i++) nodes[pos].tmp[i] = path[i];
nodes[pos].tmp[cnt] = '\0';
pos++;
return;
}
path[cnt++] = hash[root->val];
if(root->left) dfs(root->left,path,cnt);
if(root->right) dfs(root->right,path,cnt);
}
char * smallestFromLeaf(struct TreeNode* root){
char* path = malloc(sizeof(char)*10010);
int cnt = 0;
pos = 0;
dfs(root,path,cnt);
for(int i = 0; i < pos; i++) reverse(nodes[i].tmp);
for(int i = 0; i < pos; i++) printf("%s\n",nodes[i].tmp);
qsort(nodes,pos,sizeof(nodes[0]),cmp);
return nodes[0].tmp;
}
void reverse(char* s,int l,int r)
{
while(l < r)
{
char temp;
temp = s[l];
s[l] = s[r];
s[r] = temp;
l++,r--;
}
}
int cmp(const void* a,const void* b)
{
int* aa = (int*)a;
int* bb = (int*)b;
int num1 = *aa, num2 = *bb;
char* ans1 = malloc(sizeof(char)*20);
char* ans2 = malloc(sizeof(char)*20);
int cnt1 = 0, cnt2 = 0;
while(num1)
{
ans1[cnt1++] = num1 % 10 + '0';
num1 /= 10;
}
ans1[cnt1] = '\0';
while(num2)
{
ans2[cnt2++] = num2 % 10 + '0';
num2 /= 10;
}
ans2[cnt2] = '\0';
reverse(ans1,0,cnt1-1);
reverse(ans2,0,cnt2-1);
if(strcmp(ans1,ans2) > 0) return 1;
return -1;
}
int* lexicalOrder(int n, int* returnSize){
int* res = malloc(sizeof(int)*(n+10));
for(int i = 0; i < n; i++) res[i] = i+1;
*returnSize = n;
qsort(res,n,sizeof(res[0]),cmp);
return res;
}
struct Node{
int x,y;
}nodes[1010];
int maxPoints(int** points, int pointsSize, int* pointsColSize){
int n = pointsSize;
for(int i = 0; i < n; i++){
nodes[i].x = points[i][0];
nodes[i].y = points[i][1];
}
if(n == 1) return 1;
if(n == 2) return 2;
int res = 2;
for(int i = 0; i < n; i++){
for(int j = i + 1; j < n; j++){
int ans = 2;
int x1 = nodes[i].x, y1 = nodes[i].y;
int x2 = nodes[j].x, y2 = nodes[j].y;
int dx = x1 - x2, dy = y1 - y2;
for(int k = 0; k < n; k++){
if(k == i || k == j) continue;
if(dy * (nodes[k].x - x2) == dx * (nodes[k].y - y2)) ans++;
}
res = fmax(res,ans);
}
}
return res;
}
struct Node{
int x,y;
};
int dx[4] = {1,-1,0,0};
int dy[4] = {0,0,1,-1};
//能否再找到一条路径使得连续的两个点差值的最大值不超过x
bool check(int** heights,int n,int m,int x)
{
bool visit[n+1][m+1]; //(i,j) --> i*n+j这个点能否有一条路径相邻节点差值最大值不超过x的路径到这个点
memset(visit,0,sizeof(visit));
struct Node queue[100010];
int front = 0, tail = -1;
visit[0][0] = 1;
queue[++tail].x = 0,queue[tail].y = 0;
while(front <= tail)
{
struct Node node = queue[front++];
for(int i = 0; i < 4; i++){
int nx = node.x + dx[i];
int ny = node.y + dy[i];
if(nx>=0 && nx < n && ny >= 0 && ny < m && !visit[nx][ny] && abs(heights[nx][ny]-heights[node.x][node.y]) <= x){
visit[nx][ny] = true;
queue[++tail].x = nx;
queue[tail].y = ny;
}
}
}
if(visit[n-1][m-1]) return true;
return false;
}
int minimumEffortPath(int** heights, int heightsSize, int* heightsColSize){
int n = heightsSize, m = *heightsColSize;
int l = 0, r = 10000010;
while(l < r)
{
int mid = (l + r) / 2;
if(check(heights,n,m,mid)) r = mid;
else l = mid + 1;
}
return l;
}