`
xuela_net
  • 浏览: 489323 次
文章分类
社区版块
存档分类
最新评论

3月24日周赛

 
阅读更多

两场CF div2 的题目,最后还是只过7道

A.Circle Line 此题较水,判断min(正向,反向)即可。


B.New Problem 在给定一些字符串(全由小写字母组成)前提下,找出最小的串,要求它不属于任何给定串的子串。串越短、字符越小优先。

回溯写起来应该很方便

看数据量是30,而如果给定字符串长度都为2,则有26*26种可能,所以子串长度只有1或2的可能。所以枚举子串长度为1,2的可能.......

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <map>
# define MAX 105
# define INF 0x7FFFFFFF
using namespace std;

string m,n,p,q;

int main ()
{
    int a,b,c,d,f1,f2;
    int i,j;
    cin >> a;
    for(i=1; i<=a; i++)
    {
        cin >> m;
        n = n + '!';
        n = n + m;
    }
    for(i='a'; i<='z'; i++)
    {
        p = i;
        b = n.find(p);
        if(b == -1)
        {
            cout << p << endl;
            return 0;
        }
    }
    for(i='a'; i<='z'; i++)
    {
        for(j='a'; j<='z'; j++)
        {
            p = i;
            q = j;
            p = p + q;
            b = n.find(p);
            if(b == -1)
            {
                cout << p << endl;
                return 0;
            }
        }
    }
    return 0;
}

C题并查集,按照语言相通分为n类,最后只要派出n-1个人学一种语言,就能连成一片了。特殊情况,每个人都不会一种语言,此时特殊处理就行。

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
# define INF 0x7FFFFFFF
using namespace std;
#define MAX 105
int par[MAX],lan[MAX][MAX],vis[MAX],cnt[MAX];
int n,m,k;

int find(int x)
{
    while(par[x] != x)
        x = par[x];
    return x;
}

void connect(int a,int b)
{
    if(a < b)
        par[b] = a;
    else
        par[a] = b;
}

int main()
{
    int a,i,j;
    while(cin >> n >> m)
    {
        int num = 0;
        memset(lan,0,sizeof(lan));
        memset(vis,0,sizeof(vis));
        memset(cnt,0,sizeof(cnt));
        for(i=1; i<=n; i++)
            par[i] = i;
        for(i=1; i<=n; i++)
        {
            cin >> k;
            if(k == 0)
                par[i] = -1;
            for(j=0; j<k; j++)
            {
                cin >> a;
                lan[a][i] = 1;
            }
        }

        for(i=1; i<=m; i++)
        {
            memset(vis,0,sizeof(vis));
            for(j=1; j<=n; j++)
            {
                if(lan[i][j] == 1 && vis[j] == 0)
                {
                    vis[j] = 1;
                    for(int k=1; k<=n; k++)
                    {
                        if(vis[k] == 0 && lan[i][k] == 1)
                        {
                            int aa = find(j);
                            int bb = find(k);
                            if(aa != bb)
                                connect(aa,bb);
                        }
                    }
                }
            }
        }
        for(i=1; i<=n; i++)
        {
            if(par[i] == -1)
                num ++;
           else
                cnt[find(i)] = 1;
        }
        int ans = 0;
        for(i=1; i<=n; i++)
        {
            if(cnt[i] == 1)
                ans ++;
        }
        if(ans != 0)
            cout << ans - 1 + num << endl;
        else
            cout << num << endl;
    }
    return 0;
}

D.Set of Point

此题神题啊,自己是完全没理解啥意思,大神讲解后才勉强明白。

在平面坐标中给出n个点,在这n个点的任意子集中,要求找出最多为m条边的凸多边形。输入自己认为正确的n个点的坐标,不行则-1。

在坐标点数超过4,m为3(找三角形)时,找不到符合题意的点,其它则都能

为了找凸多边形,利用凸函数,所以在y = x * x上先找m个点,保证边数为m的凸多边形。而其它点与这个凸多边形相连要产生凹多边形,

找 y = - x * x - MAX,MAX为很大的数。

#include <iostream>
#include <cstdio>
using namespace std;

# define MAX 1000000

int main()
{
    int m,n,i;
    while(cin >> n >> m)
    {
        if(m == 3 && n >= 5)
        {
            cout << -1 << endl;
            continue;
        }
        for(i=0; i<m; i++)
        {
            printf("%d %d\n",i,i*i);
        }
        for(i=0; i<n-m; i++)
        {
            printf("%d %d\n",-i,-(i*i)-MAX);
        }
    }
    return 0;
}

F较水的题目,偶数不变,奇数处理即可。

G.Convex Shape

一看很神,但数据量为50,所以直接模拟各种可能得出答案。写的有些繁琐而已。

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int m, n;
char map[51][51];
bool Judge(int i0, int j0)
{
    for(int i1 = 0; i1 < n; i1++)
        for(int j1 = 0; j1 < m; j1++)
        {
            if(map[i1][j1] == 'B' && (i1 != i0 || j1 != j0))
            {
                if(i1 == i0)
                {
                    int d = j1 > j0 ? 1 : -1;
                    for(int k = j0 + d; ; k += d)
                    {
                        if(map[i0][k] == 'W') return false;
                        if(k == j1) break;
                    }
                }
                else if(j1 == j0)
                {
                    int d = i1 > i0 ? 1 : -1;
                    for(int k = i0 + d; ; k += d)
                    {
                        if(map[k][j0] == 'W') return false;
                        if(k == i1) break;
                    }
                }
                else
                {
                    bool tag = true;
                    int k, d;
                    d = i1 > i0 ? 1 : -1;
                    for(k = i0 + d; ; k += d)
                    {
                        if(map[k][j0] == 'W')
                        {
                            tag = false;
                            break;
                        }
                        if(k == i1) break;
                    }
                    if(tag)
                    {
                        d = j1 > j0 ? 1 : -1;
                        for(k = j0 + d; ; k += d)
                        {
                            if(map[i1][k] == 'W')
                            {
                                tag = false;
                                break;
                            }
                            if(k == j1) break;
                        }
                    }
                    if(!tag)
                    {
                        tag = true;
                        d = j1 > j0 ? 1 : -1;
                        for(k = j0 + d; ; k += d)
                        {
                            if(map[i0][k] == 'W')
                            {
                                tag = false;
                                break;
                            }
                            if(k == j1) break;
                        }
                        if(tag)
                        {
                            d = i1 > i0 ? 1 : -1;
                            for(k = i0 + d; ; k += d)
                            {
                                if(map[k][j1] == 'W')
                                {
                                    tag = false;
                                    break;
                                }
                                if(k == i1) break;
                            }
                        }
                    }
                    if(!tag) return false;
                }
            }
        }
    return true;
}

int main()
{
    bool ok;
    while(scanf("%d %d", &n, &m) != EOF)
    {
        ok = true;
        for(int i = 0; i < n; i++)
            scanf("%s", map[i]);
        for(int i = 0; i < n && ok; i++)
        {
            for(int j = 0; j < m && ok; j++)
            {
                if(map[i][j] == 'B')
                    ok = Judge(i, j);
            }
        }
        if(ok) printfs("YES\n");
        else printfs("NO\n");
    }
    return 0;
}

H.k-Multiple Free Set

以前看到过类似的题目,但一时想不起来怎么做,悲剧了。

把较小的先放入集合中是最优的,利用sort排序好,放入集合的数标记一下,该数的k倍大小也标记,被标记的则无法进入集合。最后进入集合个数也是最优解之一。

#include <iostream>
#include <algorithm>
#include <map>
# define MAX 1000050
using namespace std;

map <int,int> my;

int n,k,a[MAX],ans;

int main()
{
    int i,j;
    cin>> n >> k;
    for(i=0; i<n; i++)
        cin >> a[i];
    ans=0;
    sort(a,a+n);

    for(i=0; i<n; i++)
    {
        if(a[i] % k || my[a[i]/k] == 0)
        {
            ans++;
            my[a[i]] = ans;
        }
    }
    cout<< ans <<endl;
    return 0;
}

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics