暑期集训—day4—第一次暑期训练

虽然被一个陌生人给踩了。。。

但还是很开心

开始题解


A:POJ-3982


直接写一个高精度就好了。。。。我的代码被T。。。瞬间不想写了。。。反正就是一个高精度然后随便模拟一下。。。。233333直接下一题吧


B :CodeForces-807B-T-Shirt Hunt  


一道考读题的暴力。。直接写就好了。。。代码没有贴的必要


C:CodeForces-807C-Success Rate


再不写下去就没东西了。。。这道还是可以有写的地方的,蛮有趣的一道题


C. Success Rate
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

You are an experienced Codeforces user. Today you found out that during your activity on Codeforces you have made y submissions, out of which x have been successful. Thus, your current success rate on Codeforces is equal to x / y.

Your favorite rational number in the [0;1] range is p / q. Now you wonder: what is the smallest number of submissions you have to make if you want your success rate to be p / q?

Input

The first line contains a single integer t (1 ≤ t ≤ 1000) — the number of test cases.

Each of the next t lines contains four integers xyp and q (0 ≤ x ≤ y ≤ 1090 ≤ p ≤ q ≤ 109y > 0q > 0).

It is guaranteed that p / q is an irreducible fraction.

Hacks. For hacks, an additional constraint of t ≤ 5 must be met.

Output

For each test case, output a single integer equal to the smallest number of submissions you have to make if you want your success rate to be equal to your favorite rational number, or -1 if this is impossible to achieve.

Example
input
4
3 10 1 2
7 14 3 8
20 70 2 7
5 6 1 1
output
4
10
0
-1
Note

In the first example, you have to make 4 successful submissions. Your success rate will be equal to 7 / 14, or 1 / 2.

In the second example, you have to make 2 successful and 8 unsuccessful submissions. Your success rate will be equal to 9 / 24, or 3 / 8.

In the third example, there is no need to make any new submissions. Your success rate is already equal to 20 / 70, or 2 / 7.

In the fourth example, the only unsuccessful submission breaks your hopes of having the success rate equal to 1.

给你两个分数,x / y   p / q   两个操作   分数分子分母同时加一,或者分母加一,分子不变   问最少经过多少次操作能让两个分数相等


通过通分操作,让p / q分子分母同时乘 t 变成 a / b,  如果能保证b - y >= a - x   就能保证两个分数可以相等  所以问题就变成了二分放大系数t + check的二分问题  然后还要注意边界   p / q  等于0 或者 1 有可能无法达到

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
#define pb push_back
#define mp make_pair
#define LL long long
#define max3(x, y, z) max((x), max((y), (z)))
#define min3(x, y, z) min((x), min((y), (z)))
#define MAX 1010
using namespace std;

int main()
{
    int ncase;
    LL x, y, p, q;
    LL w = pow(2, 61);

    scanf("%d", &ncase);
    while(ncase --){
        cin >> x >> y >> p >> q;
        if(x * q == y * p){	///特判
            printf("0\n");
            continue;
        }
        if(p == q && x != y){
            printf("-1\n");
            continue;
        }
        if(p == 0 &&x != 0){
            printf("-1\n");
            continue;
        }
        else{
            LL l = 1;
            LL r = w / q;
            while(l <= r){
                LL mid = l + (r - l) / 2;
                LL n = mid * p;
                LL m = mid * q;
                //cout << mid << endl;
                if(n >= x &&m >= y && m - y >= n - x) r = mid - 1;
                else l = mid + 1;
            }
            cout << l * q - y << endl;
        }
    }

    return 0;
}


D-HDU-1180-诡异的楼梯

诡异的楼梯

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)
Total Submission(s): 15318    Accepted Submission(s): 4019


Problem Description
Hogwarts正式开学以后,Harry发现在Hogwarts里,某些楼梯并不是静止不动的,相反,他们每隔一分钟就变动一次方向. 
比如下面的例子里,一开始楼梯在竖直方向,一分钟以后它移动到了水平方向,再过一分钟它又回到了竖直方向.Harry发现对他来说很难找到能使得他最快到达目的地的路线,这时Ron(Harry最好的朋友)告诉Harry正好有一个魔法道具可以帮助他寻找这样的路线,而那个魔法道具上的咒语,正是由你纂写的. 
 

Input
测试数据有多组,每组的表述如下:
第一行有两个数,M和N,接下来是一个M行N列的地图,'*'表示障碍物,'.'表示走廊,'|'或者'-'表示一个楼梯,并且标明了它在一开始时所处的位置:'|'表示的楼梯在最开始是竖直方向,'-'表示的楼梯在一开始是水平方向.地图中还有一个'S'是起点,'T'是目标,0<=M,N<=20,地图中不会出现两个相连的梯子.Harry每秒只能停留在'.'或'S'和'T'所标记的格子内.
 

Output
只有一行,包含一个数T,表示到达目标的最短时间. 
注意:Harry只能每次走到相邻的格子而不能斜走,每移动一次恰好为一分钟,并且Harry登上楼梯并经过楼梯到达对面的整个过程只需要一分钟,Harry从来不在楼梯上停留.并且每次楼梯都恰好在Harry移动完毕以后才改变方向.
 

Sample Input
  
  
5 5 **..T **.*. ..|.. .*.*. S....
 

Sample Output
  
  
7
Hint
Hint
地图如下:
 

Source


给一个图,图上有若干个梯子,竖着的梯子联通上下格子,横着的梯子通过左右格子,从一个格子走到另一个格子或者走过一个梯子需要1S,梯子每秒旋转90度,问最少需要多少秒能从给定的起点走到给定的终点,不过这一题有一个坑点就是可以在一个梯子入口处等1S,虽然题目好像没说(也许吧。。),但我还是通过严格的逻辑推理推出来了这个条件(虽然现在想想是很蠢的推理)

一开始想用邻接矩阵做,后来发现我在那一霎那突然误解邻接矩阵了233333还是要多熟练一点基础的东西

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
#define pb push_back
#define mp make_pair
#define LL long long
#define max3(x, y, z) max((x), max((y), (z)))
#define min3(x, y, z) min((x), min((y), (z)))
#define MAX 1010
using namespace std;

const int N = 100010;

struct Node
{
    int x;
    int y;
    int step;
};

char ma[50][50];
int uv[3][500][500];
int vis[50][50];
int n, m;
int bx, by, ex, ey;
int xx[5] = {1, -1, 0, 0};  // 下 上 右  左
int yy[5] = {0, 0, 1, -1};

bool check(Node node)
{
    int x = node.x;
    int y = node.y;

    if(x < 1 || x > n) return false;
    if(y < 1 || y > m) return false;
    if(vis[x][y]) return false;
    if(ma[x][y] == '*' || ma[x][y] == '|' || ma[x][y] == '-') return false;

    return true;
}


int bfs(Node node)
{
    int ans = 100010;

    Node now, ne;
    queue<Node> Q;

    memset(vis, 0, sizeof(vis));
    vis[node.x][node.y] = 1;
    Q.push(node);
    while(!Q.empty()){
        now = Q.front();
        Q.pop();
        int a = now.x;
        int b = now.y;
        int step = now.step;    ///偶数  原型
        //printf("%d %d %d\n", a, b, step);
        if(a == ex && b == ey){
            ans = min(ans, step);   ///原先是直接return  因为碰见梯子是延时,所以更新最小值
            continue;
        }
        for(int i = 0; i < 4; i ++){
            int t = 0;
            int x = a + xx[i];
            int y = b + yy[i];
            if(ma[x][y] == '|'){
                if(step % 2 == 0){  ///偶时间
                    if(i == 0) x += 1;
                    if(i == 1) x -= 1;
                    if(i == 2){     
                        y += 1;
                        t = 1;      ///如果楼梯不能正好通过需要延时1S
                    }
                    if(i == 3){
                        y -= 1;
                        t = 1;      ///如果楼梯不能正好通过需要延时1S
                    }
                }
                else{
                    if(i == 2) y += 1;
                    else if(i == 3) y -= 1;
                    else if(i == 0){
                        x += 1;
                        t = 1;      ///如果楼梯不能正好通过需要延时1S
                    }
                    else if(i == 1){
                        x -= 1;
                        t = 1;      ///如果楼梯不能正好通过需要延时1S
                    }
                }
            }
            else if(ma[x][y] == '-'){
                if(step % 2 != 0){  ///偶时间
                    if(i == 0) x += 1;
                    if(i == 1) x -= 1;
                    if(i == 2){
                        y += 1;
                        t = 1;      ///如果楼梯不能正好通过需要延时1S
                    }
                    if(i == 3){
                        y -= 1;
                        t = 1;      ///如果楼梯不能正好通过需要延时1S
                    }
                }
                else{
                    if(i == 2) y += 1;
                    else if(i == 3) y -= 1;
                    else if(i == 0){
                        x += 1;
                        t = 1;
                    }
                    else if(i == 1){
                        x -= 1;
                        t = 1;
                    }
                }
            }
            ne.x = x;
            ne.y = y;
            ne.step = step + 1 + t;
            if(check(ne)){
                vis[ne.x][ne.y] = 1;
                Q.push(ne);
            }
        }
    }

    return ans;				///也许可以用优先队列。。。但是我不会写。。。
}

int main()
{
    Node be;

    while(scanf("%d%d", &n, &m) == 2){
        memset(uv, -1, sizeof(uv));
        for(int i = 1; i <= n; i ++){
            scanf("%s", ma[i] + 1);
        }
        for(int i = 1; i <= n; i ++){
            for(int j = 1; j <= m; j ++){
                if(ma[i][j] == 'S'){
                    bx = i;
                    by = j;
                }
                if(ma[i][j] == 'T'){
                    ex = i;
                    ey = j;
                }
            }
        }
        be.x = bx;
        be.y = by;
        be.step = 0;
        printf("%d\n", bfs(be));
        
    return 0;
}



今晚就这样了吧  剩下的再来补



晚安


恩我们继续贴代码

E-HDU-1757-A Simple Math Problem


这一题更加了解了矩阵快速幂,没准能把之前的B题的坑给补上。


A Simple Math Problem

Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 5068    Accepted Submission(s): 3064


Problem Description
Lele now is thinking about a simple function f(x).

If x < 10 f(x) = x.
If x >= 10 f(x) = a0 * f(x-1) + a1 * f(x-2) + a2 * f(x-3) + …… + a9 * f(x-10);
And ai(0<=i<=9) can only be 0 or 1 .

Now, I will give a0 ~ a9 and two positive integers k and m ,and could you help Lele to caculate f(k)%m.
 

Input
The problem contains mutiple test cases.Please process to the end of file.
In each case, there will be two lines.
In the first line , there are two positive integers k and m. ( k<2*10^9 , m < 10^5 )
In the second line , there are ten integers represent a0 ~ a9.
 

Output
For each case, output f(k) % m in one line.
 

Sample Input
  
  
10 9999 1 1 1 1 1 1 1 1 1 1 20 500 1 0 1 0 1 0 1 0 1 0
 

Sample Output
  
  
45 104
 

Author
linle
 

Source
 

Recommend
lcy


形如   f(n) =  a1 * f(n - 1) + a1 * f(n - 2) + a2 * f(n - 3) + ……  + at * f(n - t)

都可以用矩阵乘法表示





然后再稍微思考一下就出来了。。。我i们要算出我们构造的那个矩阵的n - 9次方,然后再根据那个构造矩阵就能得出解了


F-HDU-1016-Prime Ring Problem

给你一个n,用1~n的数字组成一个环,相邻的数字和为质数,然后输出所有可能结果,必须以1开头。
数字比较小,可以直接打表 + 搜索搞掉

G  H  都是简单题。不写了
就这样吧。。。








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值