您的位置:首页 > 其它

第六届福建省大学生程序设计竞赛

2015-12-27 19:57 337 查看
比赛没打。。。

赛后花了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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: