CF 2018, XI Samara Regional Intercollegiate Programming Contest 习题总结

题目:A. Restoring Numbers

Pavel had two positive integers a and b. He found their sum s and greatest common divisor g, and forgot a and b after that. Help him to restore the original numbers.
Input

A single line contains two integers s and g (1 ≤ s ≤ 109, 1 ≤ g ≤ 109) — sum and greatest common divisor of the numbers a and b.
Output

If Pavel made a mistake and there are no such numbers a and b, output a single number  - 1.

Otherwise, output two positive integers a and b on a single line, separated by a space. If there are multiple possible solutions, output any of them.
Examples
Input
6 2
Output
4 2

Input
7 2
Output
-1

题意:
就是有两个数a,b;给你他们的和s以及他们的gcd,求出a和b

代码如下:
#include<bits/stdc++.h>
using namespace std;
long long gcd(long long a,long long b)
{
    return b == 0? a : gcd(b,a%b);
}
int main()
{
    long long s,g,k;
    cin >> s >> g;
    if(gcd(g,s-g) == g && s != g)
    {
        cout<<max(g,s-g)<<" "<<min(g,s-g)<<endl;
    }
    else
        cout <<  "-1" << endl;
    return 0;
}
题目: C. Third-Party Software

Pavel is developing a game. To do that, he needs functions available in a third-party library too famous to be called. It is known that the function i first appeared in version ai and existed until version bi, and starting from the version bi + 1, it is absent in this library.

The library is not free and Pavel needs all the functions. Which minimal number of versions he need to purchase to be able to use all the functions?
Input

The first line contains a single integer n (1 ≤ n ≤ 200000) — the number of the functions.

Each of the next n lines contains two integers ai and bi (1 ≤ ai ≤ bi ≤ 109) — the interval of library versions where function i was available.
Output

In the first line output a single integer k — the minimal number of library versions need to be purchased to unlock all functions.

In the second line output k distinct integers — the numbers of versions need to be purchased.

If there are several possible answers, output any of them.
Example
Input
5
2 4
1 3
2 3
3 6
4 5

Output
2
3 4
题目翻译:给你n个区间代表每个英雄可以在哪几个版本玩,需要怎么购买才能玩完所有英雄。
解析: 基本的区间贪心,结构体排序按末尾排序
#include<bits/stdc++.h>
using namespace std;
struct node
{
    int s;
    int e;
    int id;
} a[200005];
int b[200005];
bool cmp(node a,node b)
{
        return a.e < b.e;
}
int main()
{
    set<int> se;
    int k;
    int s,e;
    int cnt = 1;
    cin >> k;
    for(int i = 1; i <= k; i ++)
    {
        cin >> a[i].s >> a[i].e;
        a[i].id = i;
    }
    sort(a+1,a+k+1,cmp);
    b[1] = a[1].e;
    for(int i = 2; i <= k; i ++)
    {

//        if(a[i].e <= b[cnt] || a[i].s >= b[cnt])
//        {    cnt ++;
//             b[cnt] = a[i].e;
//             se.insert(a[i].e);
//
//        }
        if(a[i].e >= b[cnt] && a[i].s <= b[cnt])
            continue;
        else
        {

            b[++ cnt] = a[i].e;

        }

    }

//    cout << se.size() << endl;
//    for(set<int> :: iterator it = se.begin();it != se.end(); it ++)
//    {
//        cout << *it << " ";
//    }
//    cout << endl;
    cout << cnt << endl;
    for(int i = 1; i <= cnt; i ++)
    {
        cout << b[i] << " ";
    }
    cout << endl;
    return 0;
}
题目:E. Substring Reverse
time limit per test
2.0 s
memory limit per test
256 MB
input
standard input
output
standard output

Two strings s and t of the same length are given. Determine whether it is possible to make t from s using exactly one reverse of some its substring.
Input

The first line contains the string s, and the secondthe string t. Both strings have the same length from 1 to 200000 characters and consist of lowercase Latin letters.
Output

Output «YES», if it is possible to reverse some substring of s to make s equal to t, and «NO», otherwise.
Examples

Input
abcdefg
abedcfg

Output
YES

Input
abcdefg
abdecfg

Output
NO
题意:就是判断这两个字符串是不是只有1个位置交换了。
解析:双指针思想从左往右遍历找到第一个字母不同的位置然后从右往左遍历找到第一个字母不同的位置,那么从这两个位置间的字符串遍历看看是否有不同的字母如果还有那么输出NO
#include<bits/stdc++.h>
using namespace std;
int main()
{
    string str_one,str_two;
    cin >> str_one;
    cin >> str_two;
    bool flag = false;
    bool flag_two = false;
    int first,second;
    int len = str_one.size();
    for(int i = 0; i < len; i ++)
    {
        if(str_one[i] != str_two[i])
        {
            first = i;
            flag = true;
            break;
        }
    }

    if(flag == false)
    {
        cout << "YES" << endl;
        return 0;
    }

    for(int i = len - 1; i > first; i--)
    {
        if(str_one[i] != str_two[i])
        {
            second = i;
            break;
        }
    }
     for(int i = first,j = second; i <= second,j >= first; i ++,j --)
        {
            if(str_one[i] != str_two[j])
            {
                flag_two = true;
                break;
            }
        }

    if(flag_two == false )
        cout <<  "YES" << endl;
    else
        cout << "NO" << endl;

    return 0;
}
题目:
H. Safe Path
You play a new RPG. The world map in it is represented by a grid of n × m cells. Any playing character staying in some cell can move from this cell in four directions — to the cells to the left, right, forward and back, but not leaving the world map.

Monsters live in some cells. If at some moment of time you are in the cell which is reachable by some monster in d steps or less, he immediately runs to you and kills you.

You have to get alive from one cell of game field to another. Determine whether it is possible and if yes, find the minimal number of steps required to do it.
Input

The first line contains three non-negative integers n, m and d (2 ≤ n·m ≤ 200000, 0 ≤ d ≤ 200000) — the size of the map and the maximal distance at which monsters are dangerous.

Each of the next n lines contains m characters. These characters can be equal to «.», «M», «S» and «F», which denote empty cell, cell with monster, start cell and finish cell, correspondingly. Start and finish cells are empty and are presented in the input exactly once.
Output

If it is possible to get alive from start cell to finish cell, output minimal number of steps required to do it. Otherwise, output «-1».

Examples

Input
5 7 1
S.M...M
.......
.......
M...M..
......F

Output
12

Input
7 6 2
S.....
...M..
......
.....M
......
M.....
.....F

Output
11

Input
7 6 2
S.....
...M..
......
......
.....M
M.....
.....F

Output
-1

Input
4 4 2
M...
.S..
....
...F

Output
-1

Note

Please note that monsters can run and kill you on start cell and on finish cell as well.
题目意思,S代表起点F代表终点给你一个n*m的图,M代表怪兽d代表攻击范围。问最少多少步可以走到终点,如果中途别吃输出-1

解析:
因为题目给的数据太大故不能用二维图存所以需要用一维图来存。那么我们需要用一次bfs把怪兽的攻击范围的点都进行标记。然后在进行第2次bfs找到最短路。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 200010;
char Map[maxn];
int dis[maxn];
typedef pair<int, int>P;
int sx,sy;
int ex,ey;
int n,m,d;
int dx[5]= {1,0,-1,0};
int dy[5]= {0,1,0,-1};
queue<P>quee;
bool check(int x,int y)///进行点是否超出地图检查
{
    if(x >= 0 && x < n && y >= 0 && y < m) return true;
    return false;
}
void bfs()
{
    while(!quee.empty())
    {
        P p = quee.front();
        quee.pop();
        if(dis[p.first * m + p.second]==0)continue;
        for(int i = 0;i < 4;i ++)
        {
            int vx = p.first + dx[i];
            int vy = p.second + dy[i];
            if(check(vx,vy))
            {
                if(dis[vx * m + vy] < dis[p.first * m + p.second] - 1)
                {
                    dis[vx * m + vy] = dis[p.first * m + p.second] - 1;
                    quee.push(P(vx,vy));
                }
            }
        }
    }
}
void bfs2(int x,int y)//求最小距离
{
    queue<P>que;
    que.push(P(x,y));
    dis[x * m + y] = 0;///把初始的距离为0
    while(!que.empty())
    {
        P p = que.front();
        que.pop();
        for(int i = 0; i < 4; i ++)
        {
            int vx = p.first + dx[i];
            int vy = p.second + dy[i];
            ///上面是搜周围
            if(check(vx,vy))
            {
                ///如果这个点为-1说明不在怪兽的攻击范围,在怪兽的攻击范围都不为-1
                if(dis[vx * m + vy] == -1)
                {
                    dis[vx * m + vy] = dis[p.first * m + p.second] + 1;
                    if(vx == ex && vy == ey)
                    {
                        break;
                    }
                    que.push(P(vx,vy));
                }
            }
        }
    }
}

int main()
{
    cin >> n >> m >> d;

    memset(dis,-1,sizeof(dis));
    for(int i = 0; i < n; i ++)
    {
        scanf("%s",&Map[i * m]);///因为题目给的数据太大地图不能拿二维数组存,所以我们将它用一维数组存这个地图
    }
    sx = -1,sy = -1,ex = -1,ey = -1;///初始化起点终点
    for(int i = 0; i < n; i ++)
    {
        for(int j = 0; j < m; j ++)
        {
            if(Map[i * m + j] == '.') continue;
            else if( Map[i * m + j] == 'M')
            {
                ///如果有怪兽就存入队列然后第一遍bfs来把怪兽攻击范围进行标记
                quee.push(P(i,j));
                dis[i * m + j] = d;///怪兽本体存入攻击范围

            }
            else if( Map[i * m + j] == 'S')
            {
                ///记录起点
                sx = i;
                sy = j;
            }
            else if(Map[i * m + j] == 'F')
            {
                ///记录终点
                ex = i;
                ey = j;

            }

        }
    }
    bfs();///进行一次bfs
    if(dis[sx * m + sy] != -1 || dis[ex * m + ey] != -1)//如果起点在攻击范围直接返回-1
    {
        puts("-1");
        return 0;
    }
    ///如果起点不在攻击范围那么开始找最短路
    bfs2(sx,sy);
    ///如果中途被吃那就输出-1
    if(dis[ex * m + ey] == -1) puts("-1");
    else
        cout << dis[ex * m + ey] << endl;
    return 0;

}
题目:

J. Parallelograms
time limit per test
2.0 s
memory limit per test
256 MB
input
standard input
output
standard output

There are n sticks, the i-th of which has length ai. Alex wants to assemble from them as many parallelograms as possible simultaneously, with each stick used at most in one parallelogram. What maximal number of parallelograms is it possible to assemble?
Input

The first line contains a single integer n (1 ≤ n ≤ 200000) — the number of sticks.

The second line contains n integers ai (1 ≤ ai ≤ 200000) — the lengths of sticks.
Output

Output a single integerthe maximal number of parallelograms that is possible to assemble.

Input
4
1 2 1 2

Output
1

Input
12
1 3 5 7 1 3 5 7 1 3 5 7

Output
2

#include<bits/stdc++.h>
using namespace std;
int a[200005];
int b[200005]={0};
bool cmp(int a,int b)
{
    return a>b;
}
int main()
{
    int n;
    cin >> n;
    for(int i = 0; i < n; i ++)
    {
        cin >> a[i];
        b[a[i]] ++;
    }
    sort(b,b+200000,cmp);
    int ans = 0;
    for(int i=0; i<= 200000; i++)
    {
        if(b[i] >= 2)
        {
            ans += b[i] / 2;
        }
    }
    cout<< ans / 2<<endl;
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值