[NOIP2014]

1.生活大爆炸版石头剪刀布

 1 #include <stdio.h>
 2 using namespace std;
 3 int a[300],b[300],n,na,nb,tot1=0,tot2=0,ans1=0,ans2=0;
 4 int f[5][5]={0,0,1,1,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,1,1,1,0,0,0};
 5 int main()
 6 {
 7     scanf("%d %d %d", &n, &na, &nb);
 8     for (int i=0;i<na;i++) 
 9         scanf("%d", &a[i]);
10     for (int i=0;i<nb;i++)
11         scanf("%d", &b[i]);
12     for (int i=1;i<=n;i++)
13     {
14         tot1+=f[a[ans1]][b[ans2]];
15         tot2+=f[b[ans2]][a[ans1]];
16         ans1++; if (ans1==na) ans1=0;
17         ans2++; if (ans2==nb) ans2=0;
18     }
19     printf("%d %d", tot1,tot2);
20     return 0;
21 }
View Code

2.联合权值

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <queue>
 4 #include <algorithm>
 5 using namespace std;
 6 struct  node
 7 {
 8     int u, v, sum, max, next;
 9 }a[400020];
10 int vis[200020], dis[200020], w[200020], tot, n, maxx;
11 int first[400020], head, tail, q[400020];
12 long long ans;
13 void addedge(int u, int v)
14 {
15     a[++tot].u = u;
16     a[tot].v = v;
17     a[tot].next = first[u];
18     first[u] = tot;
19 }
20 int bfs1()
21 {
22     q[0] = 1;
23     vis[1] = 1;
24     dis[1] =1;
25     tail = 1;
26     head = 0;
27     while (head != tail)
28     {
29         int u = q[head++];
30         for (int e = first[u]; e != -1; e = a[e].next)
31         {
32             int v = a[e].v;
33             if (!vis[v])
34             {
35                 if (w[v] > a[u].max)a[u].max = w[v];
36                 dis[v] = dis[u] + 1;
37                 a[u].sum = (a[u].sum + w[v]) % 10007;
38                 vis[v] = 1;
39                 q[tail++] = v;
40             }
41         }
42     }
43     return 0;
44 }
45 int bfs2()
46 {
47     q[0] = 1;
48     vis[1] =1;
49     tail = 1;
50     head = 0;
51     while (head != tail)
52     {
53         int u = q[head++];
54         int maxb = 0;
55         long long tmp = 0;
56         for (int e = first[u]; e != -1; e = a[e].next)
57         {
58             int v = a[e].v;
59             if (!vis[v]&&dis[v] == dis[u] + 1)
60             {
61                 ans += (tmp * w[v]);
62                 ans = ans % 10007;
63                 if (maxb * w[v] > maxx)maxx = maxb * w[v];
64                 tmp += w[v];
65                 tmp = tmp % 10007;
66                 ans += (w[u] * a[v].sum);
67                 ans = ans % 10007;
68                 if (w[u]*a[v].max > maxx)maxx = w[u]*a[v].max;
69                 vis[v] = 1;
70                 q[tail++] = v;
71                 if (w[v] > maxb)maxb = w[v];
72             }
73         }
74     }
75     return 0;
76 }
77 int main()
78 {
79     int x, y;
80     memset(first, -1, sizeof(first));
81     scanf("%d", &n);
82     for (int i = 1; i < n; i++)
83         {
84             scanf("%d%d", &x, &y);
85             addedge(x, y);
86             addedge(y, x);
87         }
88     for (int j = 1; j <= n; j++)
89         scanf("%d", &w[j]);
90     bfs1();
91     memset(vis, 0, sizeof(vis));
92     bfs2();
93     printf("%d ", maxx);
94     printf("%lld
", (ans*2)%10007);
95 }
View Code

3.飞扬的小鸟

#include <stdio.h>
#include <algorithm>
#define maxn 10005
using namespace std;
struct node
{
    int l, h;
}a[maxn];
int n, m, k, x[maxn], y[maxn], f[maxn][1005], ans, u, v, w;
int main()
{
    scanf("%d %d %d", &n, &m, &k);
    for (int i = 1; i <= n; i++)
    {
        scanf("%d %d", &x[i], &y[i]);
    }
    for (int i = 1; i <= k; i++)
    {
        scanf("%d %d %d", &u, &v, &w);
        a[u].l = v;a[u].h = w;
    }
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++)f[i][j] = 2000000000;
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= m; j++)
        {
            int t = min(m, j + x[i]);
            f[i][t] = min(f[i-1][j]+1, f[i][t]);
            f[i][t] = min(f[i][j]+1, f[i][t]); 
            //if (x[i])
          // for(int k = 1; k <= (m-j)/x[i]; k++)
           // if(j-k*x[i]>0)f[i][j] = min(f[i-1][j - k*x[i]]+k, f[i-1][j] + k);
         }
         for (int j = y[i] + 1; j <= m; j++)
         {
            f[i][j-y[i]] = min(f[i-1][j], f[i][j-y[i]]);
         }
            if (a[i].h!=0) for (int j = a[i].h; j <= m; j++)f[i][j] = 2000000000;
            if (a[i].l!=0) for (int j = 0; j <= a[i].l; j++)f[i][j] = 2000000000;   
    }
    ans = 2000000000;
    for (int i = 1; i <= m; i++)
        ans = min(ans, f[n][i]);
    if (ans < 2000000000)
        printf("1
%d
", ans);
    else if(ans = 2000000000)
    {
        ans = 0;
        for (int i = 1; i <= n; i++)
        {
            if (a[i].l||a[i].h)
            {
                int flag = 0;
                for (int j = a[i].l; j < a[i].h; j++)
                    if (f[i][j] < 2000000000)flag = 1;
                if (flag)ans++;
                else break;
            }
        }
        printf("0
%d
", ans);
    }
}
View Code

4.无线网络发射选址

#include <stdio.h>
int d, n, f[500][500], ans, x, y, k, tot;
int find(int x, int y)
{
    int tmp = 0, x1, y1, x0, y0;
    x0 = x-d;y0 = y-d;
    x1 = x + d;y1 = y + d;
    if (x1 > 128)x1 = 128;
    if (y1 > 128)y1 = 128;
    if(x0 < 0) x0 = 0;
    if(y0 < 0) y0 = 0;
    for (int i = x0; i <= x1; i++)
        for (int j = y0; j <= y1; j++)
        {
            if(f[i][j]){tmp += f[i][j];}
        }
    return tmp;
}
int main()
{
    scanf("%d", &d);
    scanf("%d", &n);
    for (int i = 1; i <= n; i++)
    {
        scanf("%d %d %d", &x, &y, &k);
        f[x][y] = k;
    }
    for (int i = 0; i <= 128; i++)
        for (int j = 0; j <= 128; j++)
        {
            int l = find(i ,j);
            if (l > ans){ans = l;}
        }
    for (int i = 0; i <= 128; i++)
        for (int j = 0; j <= 128; j++)
        {
            int l = find(i ,j);
            if (l == ans){tot++;}
        }    
    printf("%d ", tot);
    printf("%d
", ans);
}
View Code

5.寻找道路

#include <algorithm>
#define maxn 200010
using namespace std;
int q[maxn], n, m, tot, vi[maxn], vis[maxn], fa[maxn], first[maxn], first1[maxn];
int done[maxn], cnt, dis[maxn], s, t, x, y, Q[maxn], S, viss[maxn];
struct node
{
    int u, v, next;
}a[maxn], b[maxn];
void addedge(int st, int end)
{
    a[++tot].u = st;
    a[tot].v = end;
    a[tot].next = first[st];
    first[st] = tot;
}
void addedge1(int st, int end)
{
    b[++cnt].u = st;
    b[cnt].v = end;
    b[cnt].next = first1[st];
    first1[st] = cnt;
}
int bfs()
{
    q[0] = t;
    vi[t] = 1;
    int head = 0,tail = 1;
    while (head != tail)
    {
        int u = q[head++];
        for (int e = first[u]; e != -1; e = a[e].next)
        {
            int v = a[e].v;
            if (!vi[v]){
                vi[v] = 1;
                q[tail++] = v;
            }
        }
    }
    q[0] = S;
    head = 0,tail = 1;
    //viss[S] = 1;
    while (head != tail)
    {
        int u = q[head++];
        if (viss[u]) continue;
        viss[u] = 1;
        for (int e = first1[u]; e != -1; e = b[e].next)
        {
            int v = b[e].v;
            if (!vi[v])
               {
                   vi[u] = 2;
                }
            q[++tail] = v;
        }
    }
    return 0;
}
int dij()
{
    for (int i = 1; i <= n; i++)dis[i] = 2000000000;
    Q[0] = S;   
    dis[S] = 0;
    int head = 0, tail = 1;
    while (head != tail)
    {
        int u = Q[head++];
        if (done[u]) continue;
        done[u] = 1;
        for (int e = first1[u]; e != -1; e = b[e].next)
        {
            int v = b[e].v;
            if (vi[v] == 1)
                if (dis[u]+1 < dis[v])
                {
                    dis[v] = dis[u] + 1;
                    Q[tail++] = v;
                }
        }
    }
    return dis[t];
}
int main()
{

    scanf("%d %d", &n, &m);
    memset(first1, -1, sizeof(first1));
    memset(first, -1, sizeof(first));
    for (int i = 1; i <= m; i++)
    {
        scanf("%d %d", &x, &y);
        addedge(y, x);
        addedge1(x, y);
       // fa[y] = x;
    }
    scanf("%d %d", &S, &t);
    bfs();
    int flag = dij();
    if (flag < 2000000000)
    printf("%d
",flag);
    else printf("-1
");
}
View Code

6.解方程

int prime[5] = {11261,19997,22877,21893,14843}, len;
int pre[5][1000010], an[1000010];
char s[1010000];
int main()
{
    scanf("%d %d", &n, &m);
    for(int i = 0; i <= n; i++)
        {
            int flag = 1, tmp;
            scanf("%s", s+1);
            len = strlen(s+1);
            for (int t = 0; t < 5; t++)
            {
                tmp = 0;
                for (int j = 1; j <= len; j++)
                 {
                      if (s[j] == '-'){flag = -1;continue;} 
                     tmp = (tmp*10 + (s[j] - '0'))%prime[t];
                  }
                 a[t][i] = flag * tmp;
            }
        }
        for (int t = 0; t < 5; t++)
            for (int i = 0; i < prime[t]; i++)
                {
                   int v = a[t][n];
                    for (int j = n-1; j >= 0; j--) 
                       {
                        v = (a[t][j] + v*i) % prime[t];
                        }
                        if (v == 0)pre[t][i] = 1;
                    }
        for (int t = 0; t < 5; t++)
            for (int i = 0; i <= m; i++)
                {
                    if (pre[t][i%prime[t]])ans[t][i] = 1;
                    }
        for (int i = 1; i <= m; i++)
        {
            int u = 0;
            for(int t = 0; t < 5; t++)
            {
                if (ans[t][i])u++;
            }
            if(u == 5)an[++tot] = i;
        }
        printf("%d
", tot);
        for (int i = 1; i <= tot; i++)
        printf("%d
", an[i]);
}
View Code
原文地址:https://www.cnblogs.com/z52527/p/4726031.html