第七届河南省赛部分题

10401: A.物资调度

Time Limit: 2 Sec   Memory Limit: 128 MB
Submit: 106   Solved: 62
[ Submit][ Status][ Web Board]

Description

某地区发生了地震,灾区已经非常困难,灾民急需一些帐篷、衣物、食品和血浆等物资。可通往灾区的道路到处都是塌方,70%以上的路面损坏,桥梁全部被毁。国家立即启动应急预案,展开史上最大强度非作战空运行动,准备向灾区空投急需物资。

一方有难,八方支援。现在已知有N个地方分别有A1A2,….,An个物资可供调配。目前灾区需要物资数量为M

现在,请你帮忙算一算,总共有多少种物质调度方案。

假设某地方一旦被选择调配,则其物资数全部运走。

Input

第一行: K     表示有多少组测试数据。

接下来对每组测试数据有2行,第1:  N  M

                            第2行:A1  A2 ……  An

2K8     1<N100   1<M1000     1 Ai1000 

所有数据都是正整数。输入数据之间有一个空格。

假设给定的数据至少有一种调度方案。

Output

对于每组测试数据,输出一行:物资调度的总方案数

Sample Input

2
4 4
1 1 2 2
4 6
1 1 2 2

Sample Output

3
1

HINT

Source


思路: DFS 搜索

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#define INF 0x3f3f3f3f
#define eps 1e-8
#define Si(a) scanf("%d", &a)
#define Sl(a) scanf("%lld", &a)
#define Sf(a) scanf("%lf", &a)
#define Ss(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 LL long long
#define PI acos(-1.0)
using namespace std;
int n, m;
int ans;
int vis[150];
int a[150];
void dfs(int s, int sum)
{
    if(sum==m)
    {
        ans++;
        return ;
    }
    if(sum > m)  return ;
    for(int i = s; i < n; i++)
    {
        if(sum+a[i] <= m && !vis[i])
        {
            vis[i] = 1;
            dfs(i+1, sum+a[i]);
            vis[i] = 0;
        }
    }
}
int main()
{
    int t;Si(t);
    W(t)
    {
        CLR(vis, 0);
        CLR(a, 0);
        scanf("%d%d", &n,&m);
        for(int i = 0; i < n; i++) Si(a[i]);
        ans = 0;
        dfs(0, 0);
        Pi(ans);
    }
    return 0;
}
 
/**************************************************************
    Problem: 10401
    User: l1994
    Language: C++
    Result: Accepted
    Time:0 ms
    Memory:1560 kb
****************************************************************/


10400: B.海岛争霸

Time Limit: 2 Sec   Memory Limit: 128 MB
Submit: 142   Solved: 56
[ Submit][ Status][ Web Board]

Description

神秘的海洋,惊险的探险之路,打捞海底宝藏,激烈的海战,海盗劫富等等。加勒比海盗,你知道吧?杰克船长驾驶着自己的的战船黑珍珠1号要征服各个海岛的海盜,最后成为海盗王。 这是一个由海洋、岛屿和海盗组成的危险世界。杰克船长准备从自己所占领的岛屿A开始征程,逐个去占领每一个岛屿。面对危险重重的海洋与诡谲的对手,如何凭借智慧与运气,建立起一个强大的海盗帝国。
杰克船长手头有一张整个海域的海图,上面详细地记录了各个海屿的位置,以及海屿之间的通航路线。但他发现,有的航海路线太危险了,杰克船长的战船很难直接通过,他必须想方设法绕道航行;还有的岛屿根本到达不了。
杰克船长现在想把航行的危险程度降到最小。具体地来说,就是杰克船长提出若干个询问,他想知道从岛屿A 到岛屿B 有没有行驶航线,若有的话,所经过的航线,危险程度最小可能是多少。

Input

第1行:     N M        表示有N个岛屿,M条直航路线
第2~M+1行:    A   B   V   表示从岛屿A到岛屿B的航海路线的危险程度值为V。
接下面一行 :    Q           表示询问的次数。
之后有Q个行:  A B       表示询问从岛屿A 到岛屿B 所经过的航线,危险程度最小值
 1<N≤100  0<M 500   1≤ Q≤20    0 < V≤ 1000
所有数据都是正整数。输入数据之间有一个空格。
 

Output

对于每个询问,输出占一行,一个整数,表示从岛屿A 到岛屿B 所经过的航线,危险程度最小值;若从岛屿A 无法到达岛屿B,则输出-1。

Sample Input

10 8
1 2 5
1 3 2
2 3 11
2 4 6
2 4 4
6 7 10
6 10 5
10 7 2
5
2 3
1 4
3 7
6 7
8 3

Sample Output

5
5
-1
5
-1

HINT

Source


思路: 最短路 dijkstra的变形,模板改一点就行了

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#define INF 0x3f3f3f3f
#define eps 1e-8
#define Si(a) scanf("%d", &a)
#define Sl(a) scanf("%lld", &a)
#define Sf(a) scanf("%lf", &a)
#define Ss(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 LL long long
#define PI acos(-1.0)
using namespace std;
int n, m;
int map[200][200];
int vis[200];
int dis[200];
void init()
{
    for(int i = 1; i <= n; ++i)
    {
        for(int j = 1; j <= n; ++j)
            map[i][j] = i==j ? 0 : INF;
    }
}
void dij(int s,int t)
{
    CLR(vis, 0);
    int i, j, k;
    for(i = 1; i <= n; ++i)  dis[i] = map[s][i];
    vis[s] = 1;
    for(i = 1; i < n; ++i)
    {
        int minn = INF;
        k = s;
        for(j = 1; j <= n; ++j)
        {
            if(!vis[j] && minn > dis[j])
            {
                minn = dis[j];
                k = j;
            }
        }
        vis[k] = 1;
        for(j = 1; j <= n; ++j)
        {
            if(!vis[j])
                dis[j] = min(dis[j], max(dis[k],map[k][j]));
        }
    }
    if(dis[t] != INF)  Pi(dis[t]);
    else  Pi(-1);
}
int main()
{
    while(scanf("%d%d", &n,&m)!=EOF)
    {
        init();
        int i, j, k;
        int s, t, v;
        for(i = 0; i < m; ++i)
        {
            scanf("%d%d%d", &s, &t, &v);
            if(map[s][t] > v)  map[s][t] = map[t][s] = v;
        }
        int q;
        Si(q);
        W(q)
        {
            scanf("%d%d", &s, &t);
            dij(s, t);
        }
    }
    return 0;
}
 
/**************************************************************
    Problem: 10400
    User: l1994
    Language: C++
    Result: Accepted
    Time:4 ms
    Memory:1720 kb
****************************************************************/

10402: C.机器人

Time Limit: 2 Sec   Memory Limit: 128 MB
Submit: 68   Solved: 23
[ Submit][ Status][ Web Board]

Description

Dr. Kong 设计的机器人卡尔非常活泼,既能原地蹦,又能跳远。由于受软硬件设计所限,机器人卡尔只能定点跳远。若机器人站在(XY)位置,它可以原地蹦,但只可以在(XY),(X-Y),(-XY),(-X-Y),(YX),(Y-X),(-YX),(-Y-X)八个点跳来跳去。

现在,Dr. Kong想在机器人卡尔身上设计一个计数器,记录它蹦蹦跳跳的数字变化(ST),即,路过的位置坐标值之和。

你能帮助Dr. Kong判断机器人能否蹦蹦跳跳,拼出数字(ST)吗?

假设机器人卡尔初始站在(00)位置上。

Input

第一行:             K                表示有多少组测试数据。

接下来有K行,每行:X  Y  S  T    

1≤K≤10000   -2*109 <= X , Y, S, T <= 2*109

数据之间有一个空格。

Output

对于每组测试数据,输出一行:Y或者为N,分别表示可以拼出来,不能拼出来

Sample Input

3
2 1 3 3
1 1 0 1
1 0 -2 3

Sample Output

Y
N
Y

HINT

Source


思路: 扩展欧几里得。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#define INF 0x3f3f3f3f
#define eps 1e-8
#define Si(a) scanf("%d", &a)
#define Sl(a) scanf("%lld", &a)
#define Sf(a) scanf("%lf", &a)
#define Ss(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 LL long long
#define PI acos(-1.0)
using namespace std;
 
LL exgcd(LL a, LL b, LL &x, LL &y)
{
    if(b==0)
    {
        x = 1;
        y = 0;
        return a;
    }
    LL ans = exgcd(b, a%b, x, y);
    LL temp = x;
    x = y;
    y = temp - a/b*y;
    return ans;
}
int main()
{
    int k;Si(k);
    W(k)
    {
        LL x, y, s, t;
        scanf("%lld%lld%lld%lld", &x, &y, &s, &t);
        LL a, b,c, d, g;
        g = exgcd(x, y, a, b);
        c = a*t/g;
        d = b*t/g;
        a *= s/g;
        b *= s/g;
        if(s%g==0 && t%g==0)
        {
            /*a = a*(s/g);
            b = b*(s/g);
            c = c*(t/g);
            d = d*(t/g);*/
            bool flag = 0;
            for(int i = -2; i <= 2; ++i)
            {
                LL x1, y1;
                x1 = a+x/g*i;
                y1 = b-y/g*i;
                for(int j = -2; j <= 2; ++j)
                {
                    LL x2, y2;
                    x2 = c+x/g*j;
                    y2 = d-y/g*j;
                    if((x1+y2)%2 == 0 && (x2+y1)%2 == 0)
                    {
                        flag = 1;break;
                    }
                }
            }
            if(flag)  puts("Y");
            else   puts("N");
        }
        else
            puts("N");
    }
    return 0;
}
 
/**************************************************************
    Problem: 10402
    User: l1994
    Language: C++
    Result: Accepted
    Time:32 ms
    Memory:1560 kb
****************************************************************/

10403: D.山区修路

Time Limit: 2 Sec   Memory Limit: 128 MB
Submit: 82   Solved: 28
[ Submit][ Status][ Web Board]

Description

某山区的孩子们上学必须经过一条凹凸不平的土路,每当下雨天,孩子们非常艰难。现在村里走出来的Dr. Kong决定募捐资金重新修建着条路。由于资金有限,为了降低成本,对修好后的路面高度只能做到单调上升或单调下降。

为了便于修路,我们将整个土路分成了N段,每段路面的高度分别A1A2,….,An由于将每一段路垫高或挖低一个单位的花费成本相同,修路的总费用与路面的高低成正比。

现在Dr. Kong希望找到一个恰好含N个元素的不上升或不下降序列B1B2,….,Bn,作为修过的路路段的高度。要求:

 

         | A1-B1| + | A2B2| + ... + | An-Bn|------>最小

Input

第一行: K                            表示有多少组测试数据。

接下来对每组测试数据:

1:       N                表示整个土路分成了N

2~N+1行: A1  A2 ……AN     表示每段路面的高度

2k10      0Ai10    0N500    (i=1,…, N)

所有数据都是整数。 数据之间有一个空格。

数据保证| A1-B1|+| A2-B2|+ ... +| An-Bn|的最小值不会超过109

Output

对于每组测试数据,输出占一行:| A1-B1|+| A2-B2|+ ... +| An-Bn|的最小值。

Sample Input

2
7
1 3 2 4 5 3 9
5
8 6 5 6 2

Sample Output

3
1

HINT

Source


#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#define INF 0x3f3f3f3f
#define eps 1e-8
#define Si(a) scanf("%d", &a)
#define Sl(a) scanf("%lld", &a)
#define Sf(a) scanf("%lf", &a)
#define Ss(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 LL long long
#define PI acos(-1.0)
using namespace std;
const int N = 520;
int a[N], b[N], dp[N][N];
int main()
{
    int T; Si(T);
    W(T)
    {
        CLR(a, 0);
        CLR(b, 0);
        CLR(dp, 0);
        int n; Si(n);
        int i, j, k;
        for(i = 0; i < n; ++i)
        {
            Si(a[i]);
            b[i] = a[i];
        }
        sort(b, b+n);
        for(i = 0; i < n; ++i)
        {
            int m = INF;
            for(j = 0; j < n; ++j)
            {
                for(k = 0; k <= j; ++k)
                {
                    m = min(m, dp[i][k]);
                }
                dp[i+1][j] = m+abs(b[j] - a[i]);
            }
        }
        int m1 = INF;
        for(i = 0; i < n; ++i)  m1 = min(m1, dp[n][i]);
        reverse(a, a+n);
        for(i = 0; i < n; ++i)
        {
            int m = INF;
            for(j = 0; j < n; ++j)
            {
                for(k = 0; k <= j; ++k)
                {
                    m = min(m, dp[i][k]);
                }
                dp[i+1][j] = m+abs(b[j] - a[i]);
            }
        }
        int m2 = INF;
        for(i = 0; i < n; ++i)  m2 = min(m2, dp[n][i]);
        Pi(min(m1, m2));
    }
    return 0;
}
/**************************************************************
    Problem: 10403
    User: l1994
    Language: C++
    Result: Accepted
    Time:1320 ms
    Memory:2624 kb
****************************************************************/

10399: F.Turing equation

Time Limit: 1 Sec   Memory Limit: 128 MB
Submit: 159   Solved: 90
[ Submit][ Status][ Web Board]

Description

The fight goes on, whether to store  numbers starting with their most significant digit or their least  significant digit. Sometimes  this  is also called  the  "Endian War". The battleground  dates far back into the early days of computer  science. Joe Stoy,  in his (by the way excellent)  book  "Denotational Semantics", tells following story:
"The decision  which way round the digits run is,  of course, mathematically trivial. Indeed,  one early British computer  had numbers running from right to left (because the  spot on an oscilloscope tube  runs from left to right, but  in serial logic the least significant digits are dealt with first). Turing used to mystify audiences at public lectures when, quite by accident, he would slip into this mode even for decimal arithmetic, and write  things  like 73+42=16.  The next version of  the machine was  made  more conventional simply  by crossing the x-deflection wires:  this,  however, worried the engineers, whose waveforms  were all backwards. That problem was in turn solved by providing a little window so that the engineers (who tended to be behind the computer anyway) could view the oscilloscope screen from the back.

You will play the role of the audience and judge on the truth value of Turing's equations.

Input

The input contains several test cases. Each specifies on a single line a Turing equation. A Turing equation has the form "a+b=c", where a, b, c are numbers made up of the digits 0,...,9. Each number will consist of at most 7 digits. This includes possible leading or trailing zeros. The equation "0+0=0" will finish the input and has to be processed, too. The equations will not contain any spaces.

Output

For each test case generate a line containing the word "TRUE" or the word "FALSE", if the equation is true or false, respectively, in Turing's interpretation, i.e. the numbers being read backwards.

Sample Input

73+42=16
5+8=13
0001000+000200=00030
0+0=0

Sample Output

TRUE
FALSE
TRUE

HINT

Source

思路: 模拟题, 37 + 24 = 61,倒着来的~

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#define INF 0x3f3f3f3f
#define eps 1e-8
#define Si(a) scanf("%d", &a)
#define Sl(a) scanf("%lld", &a)
#define Sf(a) scanf("%lf", &a)
#define Ss(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 LL long long
#define PI acos(-1.0)
using namespace std;
int main()
{
    char s[100];
    char a[3][9];
    while(gets(s))
    {
        if(strcmp(s, "0+0=0")==0)  break;
        int ls = strlen(s);
        int i, j, k, t;
        int la, lb, lc;
        la = lb = lc = 0;
        CLR(a, 0);
        for(i = 0; ; i++)
        {
            if(s[i]=='+')  break;
            a[0][la++] = s[i]-'0';
        }
        for(j = i+1; ; j++)
        {
            if(s[j] == '=' )  break;
            a[1][lb++] = s[j]-'0';
        }
        for(k = j+1; k <ls; k++)
        {
            a[2][lc++] = s[k]-'0';
        }
        int x = 0, y = 0, z = 0;
        for(t = la-1; t >= 0; t--)  x = x*10+a[0][t];
        for(t = lb-1; t >= 0; t--)  y = y*10+a[1][t];
        for(t = lc-1; t >= 0; t--)  z = z*10+a[2][t];
        if( x+y == z ) puts("TRUE");
        else  puts("FALSE");
    }
    return 0;
}
 
/**************************************************************
    Problem: 10399
    User: l1994
    Language: C++
    Result: Accepted
    Time:0 ms
    Memory:1560 kb
****************************************************************/

10396: H.Rectangles

Time Limit: 2 Sec   Memory Limit: 128 MB
Submit: 244   Solved: 38
[ Submit][ Status][ Web Board]

Description

Given N (4 <= N <= 100)  rectangles and the lengths of their sides ( integers in the range 1..1,000), write a program that finds the maximum K for which there is a sequence of K of the given rectangles that can "nest", (i.e., some sequence P1, P2, ..., Pk, such that P1 can completely fit into P2, P2 can completely fit into P3, etc.).

 

A rectangle fits inside another rectangle if one of its sides is strictly smaller than the other rectangle's and the remaining side is no larger.  If two rectangles are identical they are considered not to fit into each other.  For example, a 2*1 rectangle fits in a 2*2 rectangle, but not in another 2*1 rectangle.

 

The list can be created from rectangles in any order and in either orientation.

Input

The first line of input gives a single integer, 1 ≤ T ≤10,  the number of test cases. Then follow, for each test case

* Line 1:       a integer N ,  Given the number ofrectangles  N<=100

* Lines 2..N+1:  Each line contains two space-separated integers  X  Y,  the sides of the respective rectangle.   1<= X , Y<=5000

Output

Output for each test case , a single line with a integer  K ,  the length of the longest sequence of fitting rectangles.

Sample Input

1
4
8 14
16 28
29 12
14 8

Sample Output

2

HINT

Source


思路: LIS

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#define INF 0x3f3f3f3f
#define eps 1e-8
#define Si(a) scanf("%d", &a)
#define Sl(a) scanf("%lld", &a)
#define Sf(a) scanf("%lf", &a)
#define Ss(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 LL long long
#define PI acos(-1.0)
using namespace std;
int dp[1010];
struct node{
    int r, c;
}p[10100];
bool cmp(node a, node b)
{
    if(a.r != b.r)
        return a.r < b.r;
    return a.c < b.c;
}
int main()
{
    int t; Si(t);
    W(t)
    {
        int n;
        Si(n);
        int i, j;
        int r, c;
        for(i = 0; i < n; ++i)
        {
            scanf("%d%d", &r, &c);
            dp[i] = 1;
            if(r > c)
            {
                p[i].r = r;
                p[i].c = c;
            }
            else
            {
                p[i].c = r;
                p[i].r = c;
            }
        }
        sort(p, p+n, cmp);
        for(i = 0; i < n; ++i)
        {
            for(j = 0; j < i; ++j)
            {
                if(p[i].r == p[j].r && p[i].c == p[j].c)  continue;
                if(dp[i] < dp[j]+1 && p[i].r >= p[j].r && p[i].c >= p[j].c)
                {
                    dp[i] = dp[j]+1;
                }
            }
        }
        sort(dp, dp+n);
        Pi(dp[n-1]);
    }
    return 0;
}
 
/**************************************************************
    Problem: 10396
    User: l1994
    Language: C++
    Result: Accepted
    Time:0 ms
    Memory:1648 kb
****************************************************************/



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值