2016summer 训练第一场

A.http://acm.hdu.edu.cn/showproblem.php?pid=5538

求表面积,只需要将所有的1*1的小块扫描一遍。将每一个块与他相邻四周进行比较,如果该快高度大,则将该快高度减去周围块高度然后累加。复杂度O(nm)

#define _CRT_SECURE_NO_DEPRECATE
#include<iostream>
#include<cmath>
#include<algorithm>
typedef long long LL;
const double EPS = 1e-8;
const double PI = acos(-1.0);
using namespace std;
const int MAXN = 55;
int n, m;
int a[MAXN][MAXN];
int dir[4][2] = { { 0, 1 }, { 0, -1 }, { -1, 0 }, { 1, 0 } };
int main(){
	int T, i, j, k;
	scanf("%d\n", &T);
	while (T--){
		memset(a, 0, sizeof(a));
		int ans = 0;
		scanf("%d%d", &n, &m);
		for (i = 1; i <= n; i++)
		for (j = 1; j <= m; j++){
			scanf("%d", &a[i][j]);
			if (a[i][j] > 0)
				ans++;
		}
		for (i = 1; i <= n; i++)
		for (j = 1; j <= m; j++){
			for (k = 0; k < 4; k++){
				int x = i + dir[k][0];
				int y = j + dir[k][1];
				if (a[x][y] < a[i][j]){
					ans += a[i][j] - a[x][y];
				}
			}
		}
		printf("%lld\n", ans);
	}
	return 0;
}

  2.http://acm.hdu.edu.cn/showproblem.php?pid=5532

原来序列要么按照升序,要么按照降序去判断,首先可以假定原序列是升序(降序同样来处理).首先将原序列从左到右扫描一遍,不断的比较相邻的两个元素,直到遇到某两元素满足

a[i]>a[i+1]或者扫描到末尾时逃出。若扫描到了末尾,则原序列是增序列,满足条件。若是遇到a[i]>a[i+1]跳出,则我们可以断定,我们要删去的元素一定是a[i]或者a[i+1],可以这样来想,如果删去的是其它元素,则该序列中还是存在a[i]和a[i+1]破坏来递增性。于是问题简单了,只需要分别去掉a[i],和a[i+1]来判断一下原序列是否是递增序列即可。同样的,当假设原序列是递减序列时,处理方法相同。

#define _CRT_SECURE_NO_DEPRECATE
#include<iostream>
#include<cmath>
#include<algorithm>
typedef long long LL;
const double EPS = 1e-8;
const double PI = acos(-1.0);
using namespace std;
const int MAXN =1000001;
int a[MAXN];
int n;
bool UpSroted(){
	int i;
	for (i = 0; i < n - 1; i++)
	  if (a[i]>a[i + 1]) //若遇到降序的则跳出
		 break;
	if (i>=n - 2) //a[i+1]后面没有数了
		return true;
	int j = i + 2;
	while (j < n - 1){
		if (a[j]>a[j + 1])
			break;
		j++;
	}
	if (j<n - 1)  //再次出现不符合
		return false;
	if (a[i] <= a[i + 2]) //去掉a[i+1]即可
		return true;
	if (a[i + 1]>a[i + 2])
		return false;
	if (i == 0)
		return true;
	if (a[i - 1] <= a[i + 1])
		return true;
	return false;
}

bool DownSroted(){
	int i;
	for (i = 0; i < n - 1; i++)
	if (a[i]<a[i + 1]) //若遇到降序的则跳出
		break;
	if (i >= n - 2) //a[i+1]后面没有数了
		return true;
	int j = i + 2;
	while (j < n - 1){
		if (a[j]<a[j + 1])
			break;
		j++;
	}
	if (j<n - 1)  //再次出现不符合
		return false;
	if (a[i] >= a[i + 2]) //去掉a[i+1]即可
		return true;
	if (a[i + 1]<a[i + 2])
		return false;
	if (i == 0)
		return true;
	if (a[i - 1] >= a[i + 1])
		return true;
	return false;
}
int main(){
	int T, i;
	scanf("%d\n", &T);
	while (T--){
		scanf("%d", &n);
		for (i = 0; i < n; i++)
			scanf("%d", &a[i]);
		bool flag = UpSroted() || DownSroted();
		if (flag)
			printf("YES\n");
		else
		    printf("NO\n");
	}
	return 0;
}

  3.http://acm.hdu.edu.cn/showproblem.php?pid=5533

原问题给出的都是整数点,这样以来就只有正方形符合要求了,只需要判断一下给定的是否是4个点,这四个点是否可以构成正方形。

#define _CRT_SECURE_NO_DEPRECATE
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
const double PI = acos(-1.0);
const int N = 300;
const double EPS = 1e-8;//实数精度
//点结构类型
struct Point{
	double x, y;
	Point(double a = 0, double b = 0){ x = a; y = b; }
};
Point operator-(Point a, Point b){
	return Point(a.x - b.x, a.y - b.y);
}
//重载==,判断点a,b是否相等
bool operator==(Point a, Point b){
	return abs(a.x - b.x) < EPS&&abs(a.y - b.y) < EPS;
}
//比较实数r1与r2的大小关系
int RlCmp(double r1, double r2 = 0){
	if (abs(r1 - r2) < EPS)
		return 0;
	return r1>r2 ? 1 : -1;
}
double Dot(Point p1, Point p2, Point p3, Point p4){
	Point a = p2 - p1;
	Point b = p4 - p3;
	return a.x*b.x + a.y*b.y;
}
//检查以p1p2和p3p4为对角线是否可以构成正方形
bool firstCheck(Point p1, Point p2, Point p3, Point p4){
	Point mid0 = Point((p1.x + p2.x) / 2, (p1.y + p2.y) / 2);
	Point mid1 = Point((p3.x + p4.x) / 2, (p3.y + p4.y) / 2);
	if (!(mid0 == mid1)) //如果中点不重合
		return false;
	return RlCmp(Dot(p1, p2, p3, p4)) == 0;  //对角线垂直
}
bool isSqual(Point P[]){
	return firstCheck(P[0], P[1], P[2], P[3]) ||
		firstCheck(P[0], P[2], P[1], P[3]) ||
		firstCheck(P[0], P[3], P[1], P[2]);
}
int main(){
	Point P[N];
	int T,i,n;
	double x, y;
	scanf("%d", &T);
	while (T--){
		scanf("%d", &n);
		for (i = 0; i < n; i++){
			scanf("%lf%lf", &x, &y);
			P[i] = Point(x, y);
		}
		if (n != 4){
			printf("NO\n");
			continue;
		}
		if (isSqual(P))
			printf("YES\n");
		else
			printf("NO\n");
	}
	return 0;
}

  4.http://acm.hdu.edu.cn/showproblem.php?pid=5536

该问题是贪心+字典树。虽然网上有O(n^3)爆力剪枝可以过,表示不会。将每一个数字的二进制从高位到低位存入到字典树中形成01串。这时候我们需要一个节点变量v,每次插入只需要将v++.接下来,枚举a[i],a[j](j>i),首先在字典树中删掉a[i]和a[j],删除做法很简单,将对应节点位置v--即可,然后用a[i]+a[j]在字典树中进行01串的匹配,匹配完后再插入a[i],a[j]准备下一次的匹配。匹配方法采用贪心思想,依次从高位向低位匹配,若当前数该位为1则去优先匹配0,若没有0匹配,则只能匹配1了。当前位置是0,则优先去匹配1,当没有1匹配,就只能匹配0了。如此下去,直到匹配到最后一位。这样有一个问题,每一个数二进制串长度不一样,给匹配带来不便,做法是,将所有的串高位补0,使得长度为32位。这样就可开心的匹配了。

#define _CRT_SECURE_NO_DEPRECATE
#include<iostream>
#include<algorithm>
typedef long long LL;
const int MAXN = 1000+10;
using namespace std;
struct TrieNode{
	TrieNode(){ memset(next, 0, sizeof(next)); v = 0; }
	TrieNode* next[2];
	LL v;
};
LL MAX;
TrieNode *root;
void Insert(LL x){
	TrieNode*p = root;
	MAX = 1;
	MAX <<= 32;
	for (LL i =MAX; i >0; i>>=1){
		LL id =(i&x)>0;
		if (p->next[id] == NULL)
			p->next[id] = new TrieNode;
		p = p->next[id];
		p->v++;
	}
}
void Delete(LL x){
	TrieNode*p = root;
	MAX = 1;
	MAX <<= 32;
	for (LL i = MAX; i >0; i >>= 1){
		LL id = (i&x)>0;
		p = p->next[id];
		p->v--;
	}
}
LL getMAX(LL x){
	TrieNode *p = root;
	MAX = 1;
	MAX <<= 32;
	LL rt,ans=x,i=-1;
	for (LL i = MAX; i >0;i>>=1){
		LL id = (x&i)>0;
		if (p->next[id ^ 1] && p->next[id ^ 1]->v > 0){
			if ((id == 0))  //说明x当前位为0,即将变为1
				ans +=i ;
			p = p->next[id ^ 1];
			continue;
		}
		if (id)  //如果x当前位置为1,则即将要变为0
			ans -= i;
		p = p->next[id];
	}
	return ans;
}
void Free(TrieNode*T){
	if (T){
		for (int i = 0; i < 2; i++)
			Free(T->next[i]);
		free(T);
		T = NULL;
	}
}
LL a[MAXN];
int main(){
	LL n,i,j,T;
	scanf("%I64d", &T);
	while (T--){
		root = new TrieNode;
		scanf("%I64d", &n);
		for (i = 0; i < n; i++){
			scanf("%I64d", &a[i]);
			Insert(a[i]);
		}
		LL ans =0;
		for (i = 0; i < n; i++){
			Delete(a[i]);
			for (j = i + 1; j < n; j++){
				Delete(a[j]);
				ans = max(ans, getMAX(a[i] + a[j]));
				Insert(a[j]);
			}
			Insert(a[i]);
		}
		printf("%I64d\n",ans);
		Free(root);
	}
	return 0;
}

  。。。。待更新

时间: 2024-10-07 10:48:58

2016summer 训练第一场的相关文章

2014多校联合训练第一场(组队训练)

这是我.potaty.lmz第二次训练,毕竟经验不足,加上水平不够,导致我们各种被碾压. A - Couple doubi: 这道题是道比较水的数论.但我们都没想出来要怎么做.后来是potaty提议打个表看看,然后lmz打出表后发现了规律.我还没细看,待研究后再补全. D - Task: 这道题一看就知道是个贪心(现在只要是有deadline的题我都觉得是贪心了).虽然想出来了,但还是不会严格证明为什么只要取满足task的且y最小(y相等时x最小)的machine就行了. 我的做法是把所有mac

2015 ACM多校训练第一场

在下面网址看效果更佳>_< http://mlz000.github.io/2015/08/07/2015-ACM%E5%A4%9A%E6%A0%A1%E8%AE%AD%E7%BB%83%E7%AC%AC%E4%B8%80%E5%9C%BA/ 题外话 这个暑假以前就决定要把这次多校的所有题全补了,中间断断续续,总算把第一场的题补全了,鄙视一下颓废的自己... hdu 5288(1001) OO's Sequence Solution 水题,定义两个数组L[i],R[i]示第i个数左侧和右侧最接

【补题】组队训练第二场 &amp; 个人训练第一场

组队第二场: C题 CodeForces Gym 100735D 题意:给你N个木棍,问他们能拼成多少个三角形. 思路:从小到大排序,然后贪心地去取. 1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #include<cmath> 6 #include<vector> 7 #include<set> 8

2015多校联合训练第一场Tricks Device(hdu5294)

题意:给一个无向图,给起点s,终点t,求最少拆掉几条边使得s到不了t,最多拆几条边使得s能到t 思路: 先跑一边最短路,记录最短路中最短的边数,总边数-最短边数就是第二个答案 第一个答案就是在最短路里面求最小割,也就是求最大流,然后根据最短路在建个新图,权为1,跑一边网络流 模板题,以后就用这套模板了 #include <iostream> #include <cstdio> #include <cstring> #include <queue> #incl

2015多校联合训练第一场Assignment(hdu5289)三种解法

题目大意:给出一个数列,问其中存在多少连续子序列,子序列的最大值-最小值 #include <iostream> #include <cstdio> #include <algorithm> #include <string> #include <cmath> using namespace std; int maxsum[100000][30]; int minsum[100000][30]; int a[100000]; int n,k; v

【补题】组队训练第一场

本来想一次补完的(正常应该补两次的)但是晚上玩dota2和rpg去了然后--又堕落了啊. 好吧进入正题,题目按照从易到难的顺序(个人感觉)其他题目现在对我来说太难了,以后再补. A题 ZOJ 3878 水题,可以用map一个一个对应,比较麻烦就用了两个字符数组,要注意\和"要转义. 1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5

2015年多校联合训练第一场OO’s Sequence(hdu5288)

题意:给定一个长度为n的序列,规定f(l,r)是对于l,r范围内的某个数字a[i],都不能找到一个对应的j使得a[i]%a[j]=0,那么l,r内有多少个i,f(l,r)就是几.问所有f(l,r)的总和是多少. 公式中给出的区间,也就是所有存在的区间. 思路:直接枚举每一个数字,对于这个数字,如果这个数字是合法的i,那么向左能扩展的最大长度是多少,向右能扩展的最大长度是多少,那么i为合法的情况就是左长度*右长度(包含i且i是合法的区间总数). 统计左长度可以判断a[i]的约数是否在前面出现过-因

【补题】多校联合训练第一场

1001  Add More Zero Problem Description There is a youngster known for amateur propositions concerning several mathematical hard problems.Nowadays, he is preparing a thought-provoking problem on a specific type of supercomputer which has ability to s

2016summer 训练第二场

1.http://acm.hdu.edu.cn/showproblem.php?pid=5112 #define _CRT_SECURE_NO_DEPRECATE #include<iostream> #include<algorithm> using namespace std; const int MAXN = 100000+10; struct Node{ int t; int x; bool operator<(Node&a){ return t < a