第九届北京化工大学程序设计竞赛网络同步赛

A题:dfs,从打到搜索

#include<iostream>
#include<math.h>
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<vector>
#include<queue>
#include<map>
#include<set>
#define B(x) (1<<(x))
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int oo = 0x3f3f3f3f;
const ll OO = 0x3f3f3f3f3f3f3f3f;
const double eps = 1e-9;
#define lson rt<<1
#define rson rt<<1|1
void cmax(int& a, int b){ if (b>a)a = b; }
void cmin(int& a, int b){ if (b<a)a = b; }
void cmax(ll& a, ll b){ if (b>a)a = b; }
void cmin(ll& a, ll b){ if (b<a)a = b; }
void cmax(double& a, double b){ if (a - b < eps) a = b; }
void cmin(double& a, double b){ if (b - a < eps) a = b; }
void add(int& a, int b, int mod){ a = (a + b) % mod; }
void add(ll& a, ll b, ll mod){ a = (a + b) % mod; }
const ll MOD = 1000000007;
const int maxn = 50;
int a[maxn];
ll sum[maxn];

int f;
void dfs(int s, int l){
	if (f) return;
	if (l > sum[s]) return;
	if (l == sum[s] || l == 0){
		f = 1;
		return;
	}
	for (int i = s; i >= 1; i--){
		if (l >= a[i])
			dfs(i - 1, l - a[i]);
	}
}

int main(){
	int n, m;
	while (scanf("%d %d", &n, &m) != EOF){
		sum[0] = 0;
		for (int i = 1; i <= n; i++){
			scanf("%d", &a[i]);
			sum[i] = sum[i - 1] + a[i];
		}
		f = 0;
		dfs(n, m);
		if (f) printf("Yes\n");
		else printf("No\n");
	}
	return 0;
}

B题:ac自动机,将前后相减等到的串去匹配,由于有负值,所以用结构体,用map存边。

#include<iostream>
#include<math.h>
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<vector>
#include<queue>
#include<map>
#include<set>
using namespace std;
#define B(x) (1<<(x))
typedef long long ll;
const int oo = 0x3f3f3f3f;
const ll OO = 1LL << 61;
const int MOD = 10007;
const int maxn = 110000;
const int maxm = 1000005;
const int SIZE = 1000005;
int Next_[maxm];
//const int type=4;
 
inline int gcd(int a, int b)
{
    return b == 0 ? a : gcd(b, a%b);
}
 
struct Node
{
    int x;
 
    Node(){}
 
    Node(int a){
        x = a;
    }
 
    bool operator==(const Node& a)const{
 
        return x == a.x;
    }
 
    bool operator!=(const Node& a)const{
 
        return x != a.x;
    }
 
    bool operator<(const Node& a)const{
        return x < a.x;
    }
 
}a[maxn], b[maxn];
 
void input(Node buff[], int len){
 
    int x, y;
    scanf("%d", &x);
    for (int i = 1; i<len; i++){
 
        scanf("%d", &y);
        buff[i] = Node(y - x);
        x = y;
    }
}
 
map<Node, int>Next[SIZE];
int fail[SIZE], flag[SIZE];
int cnt, root;
 
 
int newNode(){
 
    Next[cnt].clear();
    flag[cnt++] = 0;
    return cnt - 1;
}
 
void Init(){
 
    cnt = 1;
    root = newNode();
}
 
void Insert(Node buff[], int len){
 
    int now = root;
    Node k;
    for (int i = 1; i <= len; i++){
 
        k = buff[i];
        if (Next[now][k] == 0)
            Next[now][k] = newNode();
        now = Next[now][k];
    }//for
    flag[now]++;
}
 
void build(){
 
    fail[root] = 0;
    Node k;
    queue<int>Q;
 
    ///注:next[now][i] <=> it->second ; i <=>it->first;
    for (map<Node, int>::iterator it = Next[root].begin(); it != Next[root].end(); ++it){
 
        fail[it->second] = root;
        Q.push(it->second);
    }//for
 
    while (!Q.empty()){
 
        int now = Q.front(); Q.pop();
        flag[now] += flag[fail[now]];
        for (map<Node, int>::iterator it = Next[now].begin(); it != Next[now].end(); ++it){
 
            int temp = fail[now];
            int nxt = Next[temp][it->first];
            while (temp&&!nxt){
 
                temp = fail[temp];
                nxt = Next[temp][it->first];
            }
            if (temp) fail[it->second] = nxt;
            else fail[it->second] = root;
            Q.push(it->second);
        }//for
    }//while
}
 
ll Search(Node buff[], int len){
 
    int now = root;
    ll ans = 0;
    for (int i = 1; i <= len; i++){
 
        int nxt = Next[now][buff[i]];
        while (now&&!nxt){
 
            now = fail[now];
            nxt = Next[now][buff[i]];
        }
        if (now) now = nxt;
        else now = root;
        ans += flag[now];
    }//for
    return ans;
}
 
void get_next(Node T[], int len)
{
    int i = 0;
    Next_[i] = -1;
    int j = -1;
    while (i<len)
    {
        if (j == -1 || T[i] == T[j]){
 
            i++; j++;
            Next_[i] = j;
        }
        else j = Next_[j];
    }
}
 
ll kmp(Node S[], Node T[], int lenS, int lenT){
 
    ll ans = 0;
    int i = 0, j = 0;
    while (i<lenS){
 
        if (j == -1 || S[i] == T[j]){
 
            i++;
            j++;
        }
        else j = Next_[j];
        if (j == lenT) ans++;
    }//for
    return ans;
}
 
int main(){
 
    int T, m, n, k;
    ll ans;
    while (scanf("%d %d", &n, &m) != EOF){
 
        Init();
 
        input(a, n);
 
        ans = 0;
        if (m > 1){
 
            for (int i = 1; i <= m; i++){
 
                scanf("%d", &k);
                input(b, k);
                if (k > 1) Insert(b, k - 1);
                else ans += n;
            }
 
            build();
            ans += Search(a, n - 1);
 
        }
        else{
 
            scanf("%d", &k);
            input(b, k);
 
            if (k > 1){
                get_next(b + 1, k - 1);
                ans = kmp(a + 1, b + 1, n - 1, k - 1);
            }
            else ans += n;
        }
        cout << ans << endl; 
    }
    return 0;
}


D题:二分图,先判断二分图,然后二分匹配。

#include<iostream>
#include<math.h>
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<string>
#include<vector>
#include<queue>
#include<map>
#include<set>
#define B(x) (1<<(x))
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
void cmax(int& a, int b){ if (b>a)a = b; }
void cmin(int& a, int b){ if (b<a)a = b; }
void cmax(ll& a, ll b){ if (b>a)a = b; }
void cmin(ll& a, ll b){ if (b<a)a = b; }
void add(int& a, int b, int mod){ a = (a + b) % mod; }
void add(ll& a, ll b, ll mod){ a = (a + b) % mod; }
#define lson rt<<1
#define rson rt<<1|1
const int oo = 0x3f3f3f3f;
const ll OO = 0x3f3f3f3f3f3f3f3f;
const ll MOD = 1000000007;
const int maxn = 333;
map<string, int> mat;
char s1[20], s2[20];
int g[maxn][maxn], col[maxn];
int mac[maxn], vis[maxn];
int n;
 
bool jud(){
    queue<int>q;
    memset(col, -1, sizeof col);
    for (int i = 1; i <= n; i++){
        if (col[i] != -1)continue;
        col[i] = 1;
        q.push(i);
        while (!q.empty()){
            int u = q.front(); q.pop();
            for (int v = 1; v <= n; v++)if (g[u][v]){
                if (col[v] == -1){
                    col[v] = 1 - col[u];
                    q.push(v);
                }
                else if (col[u] == col[v]) return false;
            }
        }
    }
    return true;
}
 
int dfs(int u){
    for (int i = 1; i <= n; i++){
        if (g[u][i] && !vis[i]){
            vis[i] = 1;
            if (mac[i] == -1 || dfs(mac[i])){
                mac[i] = u;
                return 1;
            }
        }
    }
    return 0;
}
 
int Match(){
    memset(mac, -1, sizeof mac);
    int ans = 0;
    for (int i = 1; i <= n; i++){
        memset(vis, 0, sizeof vis);
        ans += dfs(i);
    }
    return ans;
}
 
int main(){
    int m;
    while (scanf("%d %d", &n, &m) != EOF){
        int cnt = 0;
        mat.clear();
        memset(g, 0, sizeof g);
        for (int i = 1; i <= m; i++){
            scanf("%s %s", s1, s2);
            if (!mat[s1])mat[s1] = ++cnt;
            if (!mat[s2])mat[s2] = ++cnt;
            g[mat[s1]][mat[s2]] = 1;
            g[mat[s2]][mat[s1]] = 1;
        }
        if (!jud()) puts("No");
        else{
            printf("%d\n", Match());
        }
    }
    return 0;
}


E题:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
int a[2][2], b[2][2], c[2][2], g[2];
#define exp 1e-6
int main()
{
    int n;
    while (~scanf("%d", &n))
    {
        int x, y, z, m;
        a[0][0] = a[1][1] = a[1][0] = a[1][1] = 0;
        b[0][0] = b[1][1] = b[1][0] = b[1][1] = 0;
        c[0][0] = c[1][1] = c[1][0] = c[1][1] = 0;
        g[0] = g[1] = 0;
        for (int i = 0; i < n; i++)
        {
            scanf("%d%d%d%d", &x, &y, &z, &m);
            a[m][x]++;
            b[m][y]++;
            c[m][z]++;
            g[m]++;
        }
        scanf("%d%d%d", &x, &y, &z);
        double xx, yy;
        xx = (a[0][x] + 1.0 / n)*b[0][y] / n*c[0][z] / n*g[0];
        yy = (a[1][x] + 1.0 / n)*b[1][y] / n*c[1][z] / n*g[1];
        if (yy - xx > exp)
            puts("Come on guys,you can do it!");
        else
            puts("Poor guys,you can go back to sleep now..");
    }
}

F题:结论题


G题:TL

H题:ORZ

I:贪心,根据上车的人数从小到大排序,然后从终点站到这往前推,如果出现负值说明这种情况无解。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
struct node
{
 
    int x, y;
}a[110000];
 
bool cmp(node a, node b)
{
    return a.y < b.y;
}
int main()
{
    int n;
    while (~scanf("%d", &n))
    {
        for (int i = 0; i < n; i++)
            scanf("%d%d", &a[i].x, &a[i].y);
        sort(a, a + n, cmp);
        long long sum = 0;
        bool flag = true;
        if (a[0].y != 0)
            puts("No");
        else
        {
            for (int i = 0; i < n; i++)
            {
                sum -= a[i].y;
                if (sum < 0)
                {
                    flag = false;
                    break;
                }
                sum += a[i].x;
            }
            if (flag)
                puts("Yes");
            else
                puts("No");
        }
    }
}

J题:乱搞

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<math.h>
using namespace std;
int x[1100000], y[1100000];
int main()
{
    int n;
    while (~scanf("%d", &n))
    {
        for (int i = 0; i < n; i++)
            scanf("%d%d", &x[i], &y[i]);
        sort(y, y + n);
        int k = y[n / 2];
        long long sum = 0;
        for (int i = 0; i < n; i++)
            sum += abs(y[i] - k);
        printf("%lld\n", sum);
    }
}




你可能感兴趣的:(第九届北京化工大学程序设计竞赛网络同步赛)