Hdu 2015 Multi-University Training Contest4

来源:互联网 发布:如何打造淘宝店铺爆款 编辑:程序博客网 时间:2024/05/20 01:34

1001

题面

Problem Description
You are one of the competitors of the Olympiad in numbers. The problem of this year relates to beatiful numbers. One integer is called beautiful if and only if all of its digitals are different (i.e. 12345 is beautiful, 11 is not beautiful and 100 is not beautiful). Every time you are asked to count how many beautiful numbers there are in the interval [a,b] (a≤b). Please be fast to get the gold medal!

Input
The first line of the input is a single integer T (T≤1000), indicating the number of testcases.

For each test case, there are two numbers a and b, as described in the statement. It is guaranteed that 1≤a≤b≤100000.

Output
For each testcase, print one line indicating the answer.

Sample Input

2
1 10
1 1000

Sample Output
10
738

题意

T(1000)次询问,每次询问给一个区间[l, r],(1 ~ 100000)。
求区间中的数每一位都不相同的数有几个。
比如12345就是每一位都不相同的数。

解析

打个表水过去就好了,手速题。

代码

#include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <stack>#include <vector>#include <queue>#include <map>#include <set>#include <climits>#include <cassert>#define LL long long#define lson lo, mi, rt << 1#define rson mi + 1, hi, rt << 1 | 1using namespace std;const int maxn = 1e6 + 10;const int inf = 0x3f3f3f3f;const double eps = 1e-8;const double pi = acos(-1.0);const double ee = exp(1.0);int cnt[100001];void init(){    memset(cnt, 0, sizeof(cnt));    int isIn[10];    for (int i = 1; i <= 100000; i++)    {        int t = i;        memset(isIn, 0, sizeof(isIn));        while (t)        {            isIn[t % 10]++;            t /= 10;        }        bool flag = true;        for (int i = 0; i <= 9; i++)        {            if (isIn[i] > 1)            {                flag = false;                break;            }        }        if (flag)        {            cnt[i] = 1;        }    }    for (int i = 1; i <= 100000; i++)    {        cnt[i] = cnt[i - 1] + cnt[i];    }}int main(){#ifdef LOCAL    freopen("in.txt", "r", stdin);#endif // LOCAL    init();    int ncase;    scanf("%d", &ncase);    while (ncase--)    {        int fr, to;        scanf("%d%d", &fr, &to);        printf("%d\n", cnt[to] - cnt[fr - 1]);    }    return 0;}

1002

题面

Problem Description
You are a “Problem Killer”, you want to solve many problems.
Now you have n problems, the i-th problem’s difficulty is represented by an integer ai (1≤ai≤109).
For some strange reason, you must choose some integer l and r (1≤l≤r≤n), and solve the problems between the l-th and the r-th, and these problems’ difficulties must form an AP (Arithmetic Progression) or a GP (Geometric Progression).
So how many problems can you solve at most?

You can find the definitions of AP and GP by the following links:
https://en.wikipedia.org/wiki/Arithmetic_progression
https://en.wikipedia.org/wiki/Geometric_progression

Input
The first line contains a single integer T, indicating the number of cases.
For each test case, the first line contains a single integer n, the second line contains n integers a1,a2,⋯,an.

T104,n106

Output
For each test case, output one line with a single integer, representing the answer.

Sample Input

2
5
1 2 3 4 6
10
1 1 1 1 1 1 2 3 4 5

Sample Output

4
6

题意

给t组测试,每组n(t组和小于100000)个数字。
求这些数字的最长连续等差数列和最长连续等比数列之间长的那个。

解析

把公差和公比拿来比较,求一段连续相同的公差公比最大的就行了。
1要特判,然后公比要用double,并且公比要注意除零。

代码

#include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <stack>#include <vector>#include <queue>#include <map>#include <set>#include <climits>#include <cassert>#define LL long long#define lson lo, mi, rt << 1#define rson mi + 1, hi, rt << 1 | 1using namespace std;const int maxn = 1e6 + 10;const int inf = 0x3f3f3f3f;const double eps = 1e-8;const double pi = acos(-1.0);const double ee = exp(1.0);int a[maxn];int cha[maxn];double bi[maxn];int main(){    #ifdef LOCAL    freopen("in.txt", "r", stdin);    #endif // LOCAL    int ncase;    scanf("%d", &ncase);    while (ncase--)    {        int n;        scanf("%d", &n);        for (int i = 0; i < n; i++)        {            scanf("%d", &a[i]);            if (i != 0)            {                cha[i] = a[i] - a[i - 1];                if (a[i - 1] != 0)                {                    bi[i] = (double)a[i] / a[i - 1];                }                else                {                    bi[i] = inf;                }            }        }        if (n == 1)        {            printf("1\n");            continue;        }        int maxxC = 1;        int maxxB = 1;        int cntC = 1;        int cntB = 1;//        cha[0] = cha[1];//        bi[0] = bi[1];        for (int i = 2; i < n; i++)        {            if (cha[i] == cha[i - 1])            {                cntC++;            }            else            {                maxxC = maxxC > cntC ? maxxC : cntC;                cntC = 1;            }            if (bi[i] == bi[i - 1] && bi[i] != inf)            {                cntB++;            }            else            {                maxxB = maxxB > cntB ? maxxB : cntB;                cntB = 1;            }        }        maxxC = maxxC = maxxC > cntC ? maxxC : cntC;        maxxB = maxxB = maxxB > cntB ? maxxB : cntB;        printf("%d\n", max(maxxB, maxxC) + 1);    }    return 0;}

1009

题面

Problem Description
In an n∗m maze, the right-bottom corner is the exit (position (n,m) is the exit). In every position of this maze, there is either a 0 or a 1 written on it.

An explorer gets lost in this grid. His position now is (1,1), and he wants to go to the exit. Since to arrive at the exit is easy for him, he wants to do something more difficult. At first, he’ll write down the number on position (1,1). Every time, he could make a move to one adjacent position (two positions are adjacent if and only if they share an edge). While walking, he will write down the number on the position he’s on to the end of his number. When finished, he will get a binary number. Please determine the minimum value of this number in binary system.

Input
The first line of the input is a single integer T (T=10), indicating the number of testcases.

For each testcase, the first line contains two integers n and m (1≤n,m≤1000). The i-th line of the next n lines contains one 01 string of length m, which represents i-th row of the maze.

Output
For each testcase, print the answer in binary system. Please eliminate all the preceding 0 unless the answer itself is 0 (in this case, print 0 instead).

Sample Input

2
2 2
11
11
3 3
001
111
101

Sample Output

111
101

题意

给一张n * m (1000)图,然后要你从(1,1)点走到(n,m)点,求走过的最小二进制数。
不要前导零。

解析

先想到dp,记忆化搜,然后发现二进制数太大了。
然后就卡题了。
dfs暴栈,要用bfs。
先用bfs找全部零的情况,若一条路径全0,那就输出0;
然后贪心只考虑向右走和向下走的情况,取出小的那个情况:
注意这里的技巧,如果两种情况都小,那么就要把两种情况同时加入vis数组中继续监视这条轨迹。

代码

#include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <stack>#include <vector>#include <queue>#include <map>#include <set>#include <climits>#include <cassert>#define LL long long#define lson lo, mi, rt << 1#define rson mi + 1, hi, rt << 1 | 1using namespace std;const int maxn = 1000 + 10;const int inf = 0x3f3f3f3f;const double eps = 1e-8;const double pi = acos(-1.0);const double ee = exp(1.0);int dir[][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};bool vis[maxn][maxn];char g[maxn][maxn];int n, m;bool ok(int x, int y){    return 1 <= x && x <= n && 1 <= y && y <= m;}struct Node{    int x, y;    Node() {}    Node(int _x, int _y)    {        x = _x;        y = _y;    }};void bfs(){    memset(vis, false, sizeof(vis));    vis[1][1] = true;    queue<Node> q;    q.push(Node(1, 1));    while (!q.empty())    {        Node now = q.front();        q.pop();        int x = now.x;        int y = now.y;        if (g[x][y] == '0')        {            for (int i = 0; i < 4; i++)            {                int nx = x + dir[i][0];                int ny = y + dir[i][1];                if (ok(nx, ny) && !vis[nx][ny])                {                    vis[nx][ny] = true;                    q.push(Node(nx, ny));                }            }        }    }}int main(){#ifdef LOCAL    freopen("in.txt", "r", stdin);#endif // LOCAL    int ncase;    scanf("%d", &ncase);    while (ncase--)    {        memset(g, 0, sizeof(g));        scanf("%d%d", &n, &m);        for (int i = 1; i <= n; i++)            scanf("%s", g[i] + 1);        bfs();        if (vis[n][m] && g[n][m] == '0')        {            puts("0");            continue;        }        int pos = 0;        for (int i = 1; i <= n; i++)        {            for (int j = 1; j <= m; j++)            {                if (vis[i][j] && pos < i + j)                {                    pos = i + j;                }            }        }        printf("1");        for (int i = pos; i < n + m; i++)        {            char c = '1';            for (int j = 1; j <= n; j++)            {                if (vis[j][i - j])                {                    if (ok(j, i - j + 1))                    {                        c = min(c, g[j][i - j + 1]);                    }                    if (ok(j + 1, i - j))                    {                        c = min(c, g[j + 1][i - j]);                    }                }            }            for (int j = 1; j <= n; j++)            {                if (vis[j][i - j])                {                    if (ok(j, i - j + 1))                    {                        if (c == g[j][i - j + 1])                            vis[j][i - j + 1] = true;                    }                    if (ok(j + 1, i - j))                    {                        if (c == g[j + 1][i - j])                            vis[j + 1][i - j] = true;                    }                }            }            printf("%c", c);        }        puts("");    }    return 0;}

1010

题面

Problem Description
XYZ is playing an interesting game called “drops”. It is played on a r∗c grid. Each grid cell is either empty, or occupied by a waterdrop. Each waterdrop has a property “size”. The waterdrop cracks when its size is larger than 4, and produces 4 small drops moving towards 4 different directions (up, down, left and right).

In every second, every small drop moves to the next cell of its direction. It is possible that multiple small drops can be at same cell, and they won’t collide. Then for each cell occupied by a waterdrop, the waterdrop’s size increases by the number of the small drops in this cell, and these small drops disappears.

You are given a game and a position (x, y), before the first second there is a waterdrop cracking at position (x, y). XYZ wants to know each waterdrop’s status after T seconds, can you help him?

1≤r≤100, 1≤c≤100, 1≤n≤100, 1≤T≤10000

Input
The first line contains four integers r, c, n and T. n stands for the numbers of waterdrops at the beginning.
Each line of the following n lines contains three integers xi, yi, sizei, meaning that the i-th waterdrop is at position (xi, yi) and its size is sizei. (1≤sizei≤4)
The next line contains two integers x, y.

It is guaranteed that all the positions in the input are distinct.

Multiple test cases (about 100 cases), please read until EOF (End Of File).

Output
n lines. Each line contains two integers Ai, Bi:
If the i-th waterdrop cracks in T seconds, Ai=0, Bi= the time when it cracked.
If the i-th waterdrop doesn’t crack in T seconds, Ai=1, Bi= its size after T seconds.

Sample Input

4 4 5 10
2 1 4
2 3 3
2 4 4
3 1 2
4 3 4
4 4

Sample Output

0 5
0 3
0 2
1 3
0 1

题意

这题的意思就是小时候玩的那个十滴水的游戏的模型。
每次炸开四个方向的水珠,然后当某个位置的水珠的siz等于5的时候,它就会炸开,然后也向四个方向射1个siz的水珠。
给一个r*c的地图,然后n个水珠,每个水珠有坐标x,y和大小siz。
然后在第0秒x0,y0处向四个方向射出一个siz的水珠。
询问T秒之后所有水珠的状态。

解析

数据量不大,纯模拟这个小游戏了。

代码

#include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <stack>#include <vector>#include <queue>#include <map>#include <set>#include <climits>#include <cassert>#define LL long long#define lson lo, mi, rt << 1#define rson mi + 1, hi, rt << 1 | 1using namespace std;const int maxn = 100 + 10;const int inf = 0x3f3f3f3f;const double eps = 1e-8;const double pi = acos(-1.0);const double ee = exp(1.0);int r, c, n, T;int id[maxn][maxn];int siz[maxn];int tim[maxn];struct Node{    int x, y;    Node(){}    Node(int _x, int _y)    {        x = _x;        y = _y;    }};Node U[maxn], D[maxn], L[maxn], R[maxn];bool flagU[maxn], flagD[maxn], flagL[maxn], flagR[maxn];Node drop[maxn];bool ok(Node a){    return 1 <= a.x && a.x <= r && 1 <= a.y && a.y <= c;}void Move(Node &a, bool& flag, int dx, int dy){    if (flag)        return;    a.x += dx;    a.y += dy;    if (!ok(a))    {        flag = true;        return;    }    int index = id[a.x][a.y];    if (index)    {        if (siz[index] <= 4)        {            siz[index]++;        }        flag = true;    }}int main(){    #ifdef LOCAL    freopen("in.txt", "r", stdin);    #endif // LOCAL    while (~scanf("%d%d%d%d", &r, &c, &n, &T))    {        memset(tim, 0, sizeof(tim));        memset(siz, 0, sizeof(siz));        memset(id, 0, sizeof(id));        for (int i = 1; i <= n; i++)        {            int x, y, s;            scanf("%d%d%d", &x, &y, &s);            siz[i] = s;            id[x][y] = i;            drop[i] = Node(x, y);        }        int x0, y0;        scanf("%d%d", &x0, &y0);        int cnt = 1;        flagU[0] = flagD[0] = flagL[0] = flagR[0] = false;        U[0] = D[0] = L[0] = R[0] = Node(x0, y0);        for (int i = 1; i <= T; i++)        {            for (int j = 0; j < cnt; j++)            {                Move(U[j], flagU[j], -1, 0);                Move(D[j], flagD[j], 1, 0);                Move(L[j], flagL[j], 0, -1);                Move(R[j], flagR[j], 0, 1);            }            for (int j = 1; j <= n; j++)            {                if (siz[j] == 5)                {                    tim[j] = i;                    id[drop[j].x][drop[j].y] = 0;                    flagU[cnt] = flagD[cnt] = flagL[cnt] = flagR[cnt] = false;                    U[cnt] = D[cnt] = L[cnt] = R[cnt] = drop[j];                    ++cnt;                    siz[j] = 0;                }            }        }        for (int i = 1; i <= n; i++)        {            if (tim[i])                printf("0 %d\n", tim[i]);            else                printf("1 %d\n", siz[i]);        }    }    return 0;}

0 0