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

来源:互联网 发布:vb flag 编辑:程序博客网 时间:2024/06/02 13:48

比赛没打。。。

赛后花了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;}


1 0
原创粉丝点击