Mutual Training for Wannafly Union #6 A(bfs)/B(规律)/E (并查集)

阿三们的oj呢,第一次印度的题。托这个服,根本查不到题解呢^q^。D题想了一半没有继续下去,太可惜了。。。。

有意思的阿三oj的题号居然不是数字,而是字母组成的,o mo shi ro i

A - Grid (spoj id:SERGRID)


You are on an nxm grid where each square on the grid has a digit on it. From a given square that has digit k on it, a Move consists of jumping exactly k squares in one of the four cardinal directions. A move cannot go beyond the edges of the grid; it does not wrap. What is the minimum number of moves required to get from the top-left corner to the bottom-right corner?

Input

Each input will consist of a single test case. Note that your program may be run multiple times on different inputs. The first line of input contains two space-separated integers n and m (1≤n,m≤500), indicating the size of the grid. It is guaranteed that at least one of n and m is greater than 1. The next n lines will each consist of m digits, with no spaces, indicating the nxm grid. Each digit is between 0 and 9, inclusive. The top-left corner of the grid will be the square corresponding to the first character in the first line of the test case. The bottom-right corner of the grid will be the square corresponding to the last character in the last line of the test case.

Output

Output a single integer on a line by itself representing the minimum number of moves required to get from the top-left corner of the grid to the bottom-right. If it isn’t possible, output -1.

Example

Input:
5 4 
2120 
1203 
3113 
1120 
1110
Output:
6
题意:
从一个图的左上角走到右下角,走的方式是在一个格子上下左右都能走,但是要走那个格子上写的数字的步数。
代码:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <vector>
#include <queue>
using namespace std;
const int maxn = 510;
const int inf = 0x3f3f3f3f;
int n,m,sx,sy,ex,ey;
int save[maxn][maxn];
char line[maxn];
int dis[maxn][maxn];
int res;
int dx[4] = {0,0,1,-1};
int dy[4] = {1,-1,0,0};
void bfs(){
    int nx,ny,i,x,y;
    pair<int, int> q;
    queue<pair<int,int> > que;
    memset(dis, inf, sizeof(dis));
    dis[sx][sy] = 0;
    que.push(make_pair(sx, sy));
    while(que.size()){
        q = que.front();
        que.pop();
        x = q.first;
        y = q.second;
        if(x==ex&&y==ey){
            break;
        }
        for(i=0;i<4;i++){
            nx = x + dx[i]*save[x][y];
            ny = y + dy[i]*save[x][y];
            if(nx>=1&&ny>=1&&nx<=n&&ny<=m&&dis[nx][ny]>dis[x][y]+1){
                que.push(make_pair(nx, ny));
                dis[nx][ny] = dis[x][y] + 1;
            }
        }
    }
}
int main(){
    int i,j,k;
    while(~scanf("%d%d",&n,&m)){
        getchar();
        for(i=1;i<=n;i++){
            scanf("%s",line);
            for(j=1;j<=m;j++){
                save[i][j] = line[j-1] - '0';
            }
            getchar();
        }
        sx = 1,sy = 1;
        ex = n,ey = m;
        bfs();
        if(dis[ex][ey]!=inf){
            printf("%d\n",dis[ex][ey]);
        }else{
            printf("-1\n");
        }
    }
    return 0;
}
 

B - Why Always Recursion

  SPOJ - ESYRCRTN 

F(1)=1 F(2)=3 F(N)=F(N-1)-F(N-2) Now you are given N, you have to find the value of F(1)+F(2)+......+F(N) .

Input

Input starts with an integer T(1<=T<=1000), denoting the number of test cases. Each test case contains an integer N(1<=N<=10^18).

Output

For each test case, print the value.

Example

Input:
2
1 
2


Output:
1
4


完全是规律的

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <vector>
#include <queue>
using namespace std;
const int maxn = 510;
const int inf = 0x3f3f3f3f;
long long n;
int res[6] = {1,3,2,-1,-3,-2};
int main(){
    int t,i;
    scanf("%d",&t);
    while(t--){
        scanf("%lld",&n);
        long long now = n%6,sum = 0;
        for(i=1;i<=now;i++){
            sum += res[i-1];
        }
        printf("%lld\n",sum);
    }
    return 0;
}


In this hot summer AIUB students decided to go on a trip to Cox’s Bazaar sea beach. Every student has some amount of money to spend in this trip. Each student belongs to some group. If student A knows student B, B knows C then A, B and C belong to the same group. In order to utilize the budget properly students hired a travel agency to get an optimal travel plan. They submitted the information about all the student’s money and relations among them. Now the agency wants to figure out the number of groups and the total budget of each group. Total budget of a group is the summation of all the student’s money in that group.

Input

The first line contains an integer T (1<=T<=50), denoting the number of test cases.

Each case starts with two integers N M. N (1<=N<=1000), denotes the number of students and M (0<=M<=(N*(N-1)/2)), denotes the number of relationships. In the next line N integers are given. The ith (1<=i<=N) integer ai (1<=ai<=100) denotes the money ith student has. Next M lines each contains two integers u v, (1<=u,v<=N and u != v) denoting that u knows v and vice versa.

Output

For each test case output “Case X: K” where X is the case number starting from 1 and K is the number of groups. In the next line output K integers, the total budget of all the groups in ascending order of budget.

Example

Input:
1
5 3
5 7 4 6 8
1 2
1 3
4 5

Output:
Case 1: 2
14 16

题意:
一堆学生出门游玩,大家抱团。A认识B,B认识C的话,ABC就会抱团一组。每个学生都有钱,现在要我们统计有几个团,每个团总共有多少钱
并查集集集集集
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
const int maxn = 2010;
const int inf = 0x3f3f3f3f;
int money[maxn];
int pre[maxn];
int n,m;
int sum[maxn];
int Find(int x){
    int r = x;
    while(pre[r]!=r){
        r = pre[r];
    }
    pre[x] = r;
    return r;
}
void mix(int a,int b){
    pre[Find(b)] = Find(a);
}
int res[maxn];
int main(){
    int t,i,p,a,b;
    int rnd = 1;
    scanf("%d",&t);
    while(t--){
        scanf("%d%d",&n,&m);
        for(i=1;i<=n;i++){
            scanf("%d",money+i);
            pre[i] = i;
        }
        for(i=1;i<=m;i++){
            scanf("%d%d",&a,&b);
            mix(a,b);
        }
        for(i=1;i<=n;i++){
            Find(i);
        }
        for(i=1;i<=n;i++){
            if(i!=pre[i]){
                money[pre[i]] += money[i];
                money[i] = inf;
            }
        }
        sort(money+1, money+1+n);
        i = 1;
        while(money[i]!=inf&&i<=n){
            i++;
        }
        printf("Case %d: %d\n",rnd++,i-1);
        for(p=1;p<i;p++){
            printf("%d%c",money[p],p==i-1?'\n':' ');
        }
        
    }
    
    return 0;
}

















  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值