博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
UESTC 2014 Summer Training #16 Div.2
阅读量:6262 次
发布时间:2019-06-22

本文共 4116 字,大约阅读时间需要 13 分钟。

  虽然被刷了还是要继续战斗下去嗯...就是基础不好,难度相对较大

 

A.

  点是顺时针给出的,可以在图上画画(脑补也行),连线x-a,x-b(x为选定的一个点,比如第一个点),就把所求面积分成了四部分,a-b左边部分是较容易求出来的,

三角形面积是直接可求,另外两个多边形面积是可以预处理出来的(多个三角形面积和)

  反正我是沒想出來...看題解也理解半天,多邊形面積转化为三角形面积和 嗯嗯

#include 
#include
#include
#include
using namespace std;const int maxn = 50000+50;struct Point{ long long x, y; Point() {} Point(long long x, long long y) { this->x = x; this->y = y; }}a[maxn];int N, Q;long long sum[maxn];long long getArea(Point a, Point b, Point c){ return abs( (c.y-a.y)*(b.x-a.x)-(b.y-a.y)*(c.x-a.x) );}int main(){#ifdef LOCAL freopen("A.in", "r", stdin);#endif scanf("%d%d", &N, &Q); for(int i = 1; i <= N; i++) { long long x, y; scanf("%lld%lld", &x, &y); a[i] = Point(x, y); } for(int i = 3; i <= N; i++) sum[i] = sum[i-1] + getArea(a[1], a[i-1], a[i]); while(Q--) { int u, v; scanf("%d%d", &u, &v); u++; v++; if(v < u) swap(u, v); long long ans = sum[N] - sum[v] + getArea(a[1], a[u], a[v]) + sum[u]; ans = min(ans, sum[N]-ans); if(ans%2 != 0) printf("%lld.5\n", ans/2); else printf("%lld.0\n", ans/2); } return 0;}

 

C.

  可以转化为二分图的最大带权匹配问题,连边+KM

  连边朴素的dfs是会挂掉的,2^25,这里介绍一个方法解决这类求子集和的问题,meet-in-the-middle algorithm

  

  大致意思是先预处理出前一半元素能组合出的数,2^13个,并且排序,然后枚举后一半能组合出的数s2,二分查找sum-s2是否存在,时间复杂度是可以接受的,具体看以上链接

  不过KM算法我不会呢...先扔这里吧

 

F.

  水题

#include 
#include
#include
using namespace std;int T, N, A, D;int main(){ cin >> T; while(T--) { cin >> N >> A >> D; cout << (2*A+(N-1)*D)*N/2 << endl; } return 0;}

 

G.

  队友搞出来的...我没怎么思考,就是排序后,检查每一个区间的极差,算有点贪心,每次选取连续的k个

#include 
#include
#include
#include
#include
using namespace std;const int maxn = 20000+50;const int inf = ~0u >> 1;int T, k, n;int h[maxn];int main(){#ifdef LOCAL freopen("G.in", "r", stdin);#endif scanf("%d", &T); while(T--) { scanf("%d%d", &n, &k); for(int i = 0; i < n; i++) scanf("%d", h+i); sort(h, h+n); int ans = inf; for(int i = 0; i+k <= n; i++) ans = min(h[i+k-1]-h[i], ans); printf("%d\n", ans); } return 0;}

 

H.

  贪心的做法,考虑最小的两个概率一定要放在最两边(选择最两边时,耗时最大)...不要问我为什么= =

  最后算下gcd除去就可以了  ps:  gcd(a,0) = a

#include 
#include
#include
#include
using namespace std;const int maxn = 40;int T, n, a, b, c;int p[maxn], arranged[maxn];int gcd(int a, int b){ return b == 0 ? a: gcd(b, a%b);}int main(){#ifdef LOCAL freopen("H.in", "r", stdin);#endif scanf("%d", &T); while(T--) { scanf("%d%d%d%d", &n, &a, &b, &c); for(int i = 0; i < n; i++) scanf("%d", p+i); sort(p, p+n); int front = 0, rear = n-1; for(int i = 0; i < n; i++) arranged[i%2?rear--:front++] = p[i]; int ans = 0; for(int i = 0; i < n; i++) for(int j = 0; j < n; j++) ans += arranged[i]*arranged[j]*((i-j)*(i-j)*a+b*abs(i-j)+c); printf("%d/%d\n", ans/gcd(ans, 10000), 10000/gcd(10000, ans)); } return 0;}

 

I.

  这道题我是无论如何也想不到这样优化的...

  N=a1+a2+...+an,  P=a1a2...an

  a1...an都能唯一分解为素数相乘,因此P一定是2~N的素数乘积,似乎通过一个素数表来dfs

  现在要考虑另一点(很多blog没有指出) 最原始的办法是dfs 1~N 现在我们dfs这个素数表,是否覆盖了所有的情况呢?

  事实上2,3的组合就能覆盖2~N的所有数,即使用素数替换之前dfs的数

  例如10 = 6+4  原始的做法会去 dfs 4 6  而现在dfs  2 2 2 3 素数的组合

  想了半天其实自己也不是很理解...

  PS:第一次使用set 资料给出基本操作都是O(logn)!!

#include 
#include
#include
#include
#include
using namespace std;const int prime[] = {
2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71}; int T, N, P;set
cnt;void dfs(int x, int r, long long p){ if(x >= 20) return; cnt.insert(p);// cout << "insert " << p <

 

转载于:https://www.cnblogs.com/gemmeg/p/3898726.html

你可能感兴趣的文章
几款开源的图形化Redis客户端管理软件推荐
查看>>
数据库设计中常见表结构的设计技巧
查看>>
CVPR论文《100+ Times Faster Weighted Median Filter (WMF)》的实现和解析(附源代码)。...
查看>>
MATLAB模糊逻辑(2)
查看>>
linux 内核模块管理
查看>>
【每日一摩斯】-【序列】-续-RAC and Sequences (853652.1)
查看>>
把一个select查询结果插入到一个表(可选指定字段和值实例)
查看>>
使用windbg抓取崩溃文件和分析的过程
查看>>
ViewHolder模式超简洁写法
查看>>
项目管理学习笔记之三.绩效分析
查看>>
php十行代码将xml转成数组
查看>>
centos 7 执行 groupinstall报错
查看>>
Web开发入门
查看>>
Flex开发小结(1)如何使用AdvancedDataGrid
查看>>
AFNetworking 下载文件断点续传操作
查看>>
Jar mismatch! Fix your dependencies
查看>>
哀悼日, 网页变灰的实现
查看>>
php:检测用户当前浏览器是否为IE浏览器
查看>>
linux命令备份
查看>>
10个你可能不知道的JavaScript小技巧
查看>>