第六届福建省大学生程序设计竞赛
2015-12-27 19:57
337 查看
比赛没打。。。
赛后花了2个多小时1A5道题,好激动啊。先补作业去了,一堆实验报告等着我。 o(╯□╰)o。
A题链接:点我
题意:给你n个电池的电量(100为满)和你可以充的电量m,问最多可以充满几个电池。
签到题吧。
AC代码:
B题链接:点我
题意:给你两个圆,问你切线有多少条,无数条时输出-1。
思路:判断两圆位置,分类讨论即可。
相交,相切,相离,重合,内含。
AC代码:
C题链接:点我
题意:0-1背包问题,扩大了背包容量和物品重量而已。
思路:容量过大,转化下思路就好了。设置dp[i][j]为前i个物品获得价值为j时所需的最小容量。
状态转移 dp[i][j] = min(dp[i-1][j], dp[i][j-val[i]] + w[i])。优化掉一维就可以了。
AC代码:
E题链接:点我
题意:给你n个介于(0和m的数),你可以将0变成任意一个介于1-m的数。问你最长连续序列的长度。0是不合法的。
比如说 2 6 5 3 4 就算是一个长度为5的连续序列。序列不按顺序也行。
思路:记录0的个数cnt,排序去重后,分成若干个连续的块。求出每个块的长度l和起点s,终点e。
问题就变成最多花费cnt连通若干个块,使得连通的块最长。
这样用dp思想,枚举最后的一个连通的块,对每个块i求出其最远的起点块p即(连通p-i花费的代价最多为cnt)。
这里需要二分,为了进行二分操作,需要先统计花费的前缀和 即连通前i个块花费的总代价。
dp的过程中维护下最大值就好了。过程中注意边界,因为所有数的范围是1-m。
时间复杂度O(nlogn)。
AC代码:
J题链接:点我
题意:给你两个队伍A和B,分别有n、m个人。现在要进行三次比赛来决定胜负,一场比赛两支队伍都要出一定的人数
Ai、Bi,若Ai >= Bi则A胜反之B胜。问你队伍A是否存在一种安排方案,使得队伍B无论怎样出人都会输掉比赛。
5min帮别人YY一个思路,没想到那货就这样AC了。 O__O "…
思路:把n分成三份,把剩余的部分均分给其中一份(余2就均分给其中两份)。判断最小的两份之和 + 2 是否小于等于 m。
AC代码:
赛后花了2个多小时1A5道题,好激动啊。先补作业去了,一堆实验报告等着我。 o(╯□╰)o。
A题链接:点我
题意:给你n个电池的电量(100为满)和你可以充的电量m,问最多可以充满几个电池。
签到题吧。
AC代码:
#include <cstdio> #include <cstring> #include <cmath> #include <cstdlib> #include <algorithm> #include <queue> #include <stack> #include <map> #include <vector> #define INF 0x3f3f3f3f #define eps 1e-8 #define MAXN (100+10) #define MAXM (100000) #define Ri(a) scanf("%d", &a) #define Rl(a) scanf("%lld", &a) #define Rf(a) scanf("%lf", &a) #define Rs(a) scanf("%s", a) #define Pi(a) printf("%d\n", (a)) #define Pf(a) printf("%.2lf\n", (a)) #define Pl(a) printf("%lld\n", (a)) #define Ps(a) printf("%s\n", (a)) #define W(a) while(a--) #define CLR(a, b) memset(a, (b), sizeof(a)) #define MOD 1000000007 #define LL long long #define lson o<<1, l, mid #define rson o<<1|1, mid+1, r #define ll o<<1 #define rr o<<1|1 #define PI acos(-1.0) using namespace std; int a[MAXN]; int main() { int t; Ri(t); W(t) { int n, m; Ri(n); Ri(m); for(int i = 0; i < n; i++) Ri(a[i]), a[i] = 100-a[i]; sort(a, a+n); int ans = 0; for(int i = 0; i < n; i++) { if(m - a[i] >= 0) ans++; else break; m -= a[i]; } Pi(ans); } return 0; }
B题链接:点我
题意:给你两个圆,问你切线有多少条,无数条时输出-1。
思路:判断两圆位置,分类讨论即可。
相交,相切,相离,重合,内含。
AC代码:
#include <cstdio> #include <cstring> #include <cmath> #include <cstdlib> #include <algorithm> #include <queue> #include <stack> #include <map> #include <vector> #define INF 0x3f3f3f3f #define eps 1e-8 #define MAXN (100000+10) #define MAXM (100000) #define Ri(a) scanf("%d", &a) #define Rl(a) scanf("%lld", &a) #define Rf(a) scanf("%lf", &a) #define Rs(a) scanf("%s", a) #define Pi(a) printf("%d\n", (a)) #define Pf(a) printf("%.2lf\n", (a)) #define Pl(a) printf("%lld\n", (a)) #define Ps(a) printf("%s\n", (a)) #define W(a) while(a--) #define CLR(a, b) memset(a, (b), sizeof(a)) #define MOD 1000000007 #define LL long long #define lson o<<1, l, mid #define rson o<<1|1, mid+1, r #define ll o<<1 #define rr o<<1|1 #define PI acos(-1.0) using namespace std; int dis(int x1, int y1, int x2, int y2){ return (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2); } int main() { int t; Ri(t); W(t) { int x1, y1, r1; int x2, y2, r2; Ri(x1); Ri(y1); Ri(r1); Ri(x2); Ri(y2); Ri(r2); int d = dis(x1, y1, x2, y2); int l = abs(r1-r2)*abs(r1-r2); int r = (r1+r2)*(r1+r2); if(x1 == x2 && y1 == y2 && r1 == r2) printf("-1\n"); else if(d == r) printf("3\n"); else if(d == l) printf("1\n"); else if(d >= l && d <= r) printf("2\n"); else if(d > r) printf("4\n"); else printf("0\n"); } return 0; }
C题链接:点我
题意:0-1背包问题,扩大了背包容量和物品重量而已。
思路:容量过大,转化下思路就好了。设置dp[i][j]为前i个物品获得价值为j时所需的最小容量。
状态转移 dp[i][j] = min(dp[i-1][j], dp[i][j-val[i]] + w[i])。优化掉一维就可以了。
AC代码:
#include <cstdio> #include <cstring> #include <cmath> #include <cstdlib> #include <algorithm> #include <queue> #include <stack> #include <map> #include <vector> #define INF 0x3f3f3f3f #define eps 1e-8 #define MAXN (500+10) #define MAXM (100000) #define Ri(a) scanf("%d", &a) #define Rl(a) scanf("%lld", &a) #define Rf(a) scanf("%lf", &a) #define Rs(a) scanf("%s", a) #define Pi(a) printf("%d\n", (a)) #define Pf(a) printf("%.2lf\n", (a)) #define Pl(a) printf("%lld\n", (a)) #define Ps(a) printf("%s\n", (a)) #define W(a) while(a--) #define CLR(a, b) memset(a, (b), sizeof(a)) #define MOD 1000000007 #define LL long long #define lson o<<1, l, mid #define rson o<<1|1, mid+1, r #define ll o<<1 #define rr o<<1|1 #define PI acos(-1.0) using namespace std; int dp[10000]; int v[510], w[510]; int main() { int t; Ri(t); W(t) { int N, W; Ri(N); Ri(W); int sumv = 0; for(int i = 0; i < N; i++) { Ri(w[i]); Ri(v[i]); sumv += v[i]; } CLR(dp, INF); dp[0] = 0; for(int i = 0; i < N; i++) for(int j = sumv; j >= v[i]; j--) dp[j] = min(dp[j], dp[j-v[i]] + w[i]); for(int i = sumv; i >= 0; i--) { if(dp[i] <= W) { printf("%d\n", i); break; } } } return 0; }
E题链接:点我
题意:给你n个介于(0和m的数),你可以将0变成任意一个介于1-m的数。问你最长连续序列的长度。0是不合法的。
比如说 2 6 5 3 4 就算是一个长度为5的连续序列。序列不按顺序也行。
思路:记录0的个数cnt,排序去重后,分成若干个连续的块。求出每个块的长度l和起点s,终点e。
问题就变成最多花费cnt连通若干个块,使得连通的块最长。
这样用dp思想,枚举最后的一个连通的块,对每个块i求出其最远的起点块p即(连通p-i花费的代价最多为cnt)。
这里需要二分,为了进行二分操作,需要先统计花费的前缀和 即连通前i个块花费的总代价。
dp的过程中维护下最大值就好了。过程中注意边界,因为所有数的范围是1-m。
时间复杂度O(nlogn)。
AC代码:
#include <cstdio> #include <cstring> #include <cmath> #include <cstdlib> #include <algorithm> #include <queue> #include <stack> #include <map> #include <vector> #define INF 0x3f3f3f3f #define eps 1e-8 #define MAXN (100000+10) #define MAXM (100000) #define Ri(a) scanf("%d", &a) #define Rl(a) scanf("%lld", &a) #define Rf(a) scanf("%lf", &a) #define Rs(a) scanf("%s", a) #define Pi(a) printf("%d\n", (a)) #define Pf(a) printf("%.2lf\n", (a)) #define Pl(a) printf("%lld\n", (a)) #define Ps(a) printf("%s\n", (a)) #define W(a) while(a--) #define CLR(a, b) memset(a, (b), sizeof(a)) #define MOD 1000000007 #define LL long long #define lson o<<1, l, mid #define rson o<<1|1, mid+1, r #define ll o<<1 #define rr o<<1|1 #define PI acos(-1.0) using namespace std; struct Node{ int s, e, l; }; Node num[MAXN]; int top; int rec[MAXN], used[MAXN]; int main() { int t; Ri(t); W(t) { int n, m; Ri(n); Ri(m); int cnt = 0; int len = 1; for(int i = 1; i <= n; i++) { int a; Ri(a); if(a) rec[len++] = a; else cnt++; } int R; if(len != 1) { sort(rec+1, rec+len); R = 2; for(int i = 2; i < len; i++) if(rec[i] != rec[i-1]) rec[R++] = rec[i]; sort(rec+1, rec+R); rec[R] = -1; } else R = 1; int sum = 1; top = 0; for(int i = 1; i <= R-1; i++) { // Pi(rec[i]); if(rec[i] != rec[i+1] - 1) { ++top; num[top].l = sum; num[top].e = rec[i]; num[top].s = rec[i] - sum + 1; sum = 1; } else sum++; } // for(int i = 1; i <= top; i++) // printf("%d %d %d\n", num[i].s, num[i].e, num[i].l); used[1] = 0; for(int i = 2; i <= top; i++) used[i] = used[i-1] + num[i].s - num[i-1].e - 1;// Pi(used[i]); int ans = 0; for(int i = 1; i <= top; i++) { int v = used[i] - cnt; int p; if(cnt >= used[i]) p = 1; else p = lower_bound(used, used+top+1, v) - used; //printf("---%d ", p); int have = num[i].e - num[p].s + 1; int cost = used[i] - used[p]; if(cnt > cost) { int left = num[p].s - 1; int right = m - num[i].e; have += min(left + right, cnt - cost); } ans = max(ans, have); //Pi(ans); } if(ans == 0) ans = max(ans, min(cnt, m)); Pi(ans); } return 0; }
J题链接:点我
题意:给你两个队伍A和B,分别有n、m个人。现在要进行三次比赛来决定胜负,一场比赛两支队伍都要出一定的人数
Ai、Bi,若Ai >= Bi则A胜反之B胜。问你队伍A是否存在一种安排方案,使得队伍B无论怎样出人都会输掉比赛。
5min帮别人YY一个思路,没想到那货就这样AC了。 O__O "…
思路:把n分成三份,把剩余的部分均分给其中一份(余2就均分给其中两份)。判断最小的两份之和 + 2 是否小于等于 m。
AC代码:
#include <cstdio> #include <cstring> #include <cmath> #include <cstdlib> #include <algorithm> #include <queue> #include <stack> #include <map> #include <vector> #define INF 0x3f3f3f3f #define eps 1e-8 #define MAXN (500+10) #define MAXM (100000) #define Ri(a) scanf("%d", &a) #define Rl(a) scanf("%lld", &a) #define Rf(a) scanf("%lf", &a) #define Rs(a) scanf("%s", a) #define Pi(a) printf("%d\n", (a)) #define Pf(a) printf("%.2lf\n", (a)) #define Pl(a) printf("%lld\n", (a)) #define Ps(a) printf("%s\n", (a)) #define W(a) while(a--) #define CLR(a, b) memset(a, (b), sizeof(a)) #define MOD 1000000007 #define LL long long #define lson o<<1, l, mid #define rson o<<1|1, mid+1, r #define ll o<<1 #define rr o<<1|1 #define PI acos(-1.0) using namespace std; int main() { int t; Ri(t); W(t) { int n, m; Ri(n); Ri(m); int a = n / 3; int b = a, c = a; int yu = n % 3; if(yu == 1) a++; if(yu == 2) a++, b++; if(b + c + 2 <= m) printf("No\n"); else printf("Yes\n"); } return 0; }
相关文章推荐
- 使用XListView框架进行上拉加载和下拉刷新
- 创建被图像填充的组件
- 创建被图像填充的组件
- C# 字段(Field)、属性(Property)、特性(Attribute)
- LVM2的基本应用及操作
- 关于JSP简单入门
- 循环节入门
- Hadoop IO基于文件的数据结构详解【列式和行式数据结构的存储策略】
- spring mvc下shiro的session,request等问题
- Hadoop IO基于文件的数据结构详解【列式和行式数据结构的存储策略】
- 网红经济背后的故事
- Linux安装Memcached服务
- [转]三层之抽象工厂加反射实例
- 机器学习:从线性回归说起
- VB.NET——宏观把控
- Nginx对某个文件夹或整个站点进行登录认证的方法
- 第一个AngularJS指令
- AFN post的数据编码格式问题
- 编译型语言、解释型语言与脚本语言三大类型详解
- python字典访问的三种方法