首页 > 其他 > 详细

大二第一次东北团队训练赛

时间:2015-03-23 21:11:56      阅读:232      评论:0      收藏:0      [点我收藏+]

这次A的题全是亮哥敲的,丧失也出了不少思路,基本就我在躺,得让自己的思路和代码能力迅速提高起来,尽自己最大的力量吧。

比赛后又敲了一遍。

A.给前三个数求第k项,需判断是等差还是等比数列。

技术分享
#include<iostream>
#include<stdio.h>
using namespace std;
const long long mod = 200907;
long long a[4];
long long sort_pow(long long k, long long m){
    if(k == 0)
        return 1;
    if(k % 2){
        long long uu = sort_pow(k/2, m);
        return (uu*uu*m) % mod;
    }else{
        long long uu = sort_pow(k/2, m);
        return (uu*uu) % mod;
    }
}
int main(){
    long long t;
    scanf("%I64d", &t);
    while(t--){
        for(long long i = 0; i < 3; i++){
            scanf("%I64d", &a[i]);
        }
        long long k;
        scanf("%I64d", &k);
        if(a[2] - a[1] == a[1] - a[0]){
            printf("%I64d\n", ((a[2] -a[1]) % mod *(k-1)+a[0]) %mod);
        }else{
            printf("%I64d\n", (a[0] * sort_pow(k-1,a[1]/a[0]))% mod);
        }
    }

}
View Code

B.两种操作

M a b。把a所在的堆放到b所在的堆上面。

C a:问a下面有多少箱子

就是带权并查集,不过好久没敲代码了,敲得又慢bug又多,最后还是星星重构了一遍过了

技术分享
#include<iostream>
#include<string.h>
#include<stdio.h>
using namespace std;
const int maxa = 30005;
int fa[maxa];
int val[maxa];
int up_box[maxa];
int find(int i){
    if(i == fa[i]){
        return i;
    }
    find(fa[i]);
    val[i] += val[fa[i]];
    return fa[i] = fa[fa[i]];

}
void add(int x, int y){
    int fx = find(x);
    int fy = find(y);
    int upx = up_box[fx];
    int upy = up_box[fy];
    if(fx != fy){//printf("*");
        fa[fx] = upy;
        val[fx] = 1;
        up_box[fy] = upx;
    }
}
int main(){
    int n;
    while(scanf("%d", &n)!=EOF){
        for(int i = 1; i < maxa; i++){
            fa[i] = i;
            val[i] = 0;
            up_box[i] = i;
        }
        while(n--){
            char c;
            scanf("\n%c", &c);
            if(c == M){
                int a, b;
                scanf("%d%d", &a, &b);
                add(a, b);
            }else{
                int a;
                scanf("%d", &a);
                find(a);
                printf("%d\n", val[a]);
            }
        }
        /*for(int i = 1; i <= 6; i++){
            find(i);
            printf("%d ", val[i]);
        }*/
    }
}
View Code

C.每次能把两行或者两列互换,只换列就可以,如果某一列第x个位置是1,那么他就可以和x建立一个联系,如果只换列不可以的话换行也是不行的,将列想成是男人,行想成是女人,如果换行的话说明两个女人调换了,那么对能否能够全部匹配上并没有影响,并查集模板。

技术分享
#include<iostream>
#include<string.h>
#include<stdio.h>
#include<vector>
using namespace std;
const int maxa = 104;
int mp[maxa][maxa];
vector<int>g[maxa];
int from[maxa], tot;
bool use[maxa];
    int n;
bool match(int x){
    for(int i = 0;i  < g[x].size(); i++){
        if(!use[g[x][i]]){
            use[g[x][i]] = true;
            if(from[g[x][i]] == -1 || match(from[g[x][i]])){
                from[g[x][i]] = x;
                return true;
            }
        }
    }
    return false;
}
int hunger(){
    tot = 0;
    memset(from, 255, sizeof(from));
    for(int i = 1; i <= n; i++){
        memset(use, 0, sizeof(use));
        if(match(i))
            ++tot;
    }
    return tot;
}
int main(){
    while(scanf("%d", &n)!=EOF){
        for(int i = 1; i <= n; i++) g[i].clear();
        for(int i = 0; i < n; i++){
            for(int k = 0;k  < n; k++){
                scanf("%d", &mp[i][k]);
            }
        }
        for(int i = 0; i < n; i++){
            for(int k = 0; k <n ; k++){
                if(mp[k][i]){
                    g[k+1].push_back(i+1);
                }
            }
        }
        if(hunger() == n){
            int sum = 0;
            int ans[maxa][2];
            int m = n;
            while(m--)
            for(int i = 1; i <= n; i++){
                if(from[i] != i){
                    int a = ans[sum][0] = i;
                    int b = ans[sum++][1] = from[i];
                    swap(from[a], from[b]);
                }
            }
            printf("%d\n", sum);
            for(int i =0 ;i < sum; i++){
                printf("C %d %d\n", ans[i][0], ans[i][1]);
            }
        }else printf("-1\n");
    }
}
View Code

D.给出n个数,形成队列必须两两之差不大于k,问有多少种情况。

亮哥思路每次从1到n依次往里面插,插m的时候找出m-1时的所有种情况,比m-k小的全用"_" 表示,每次状态都会减一,思路吊的不行。

技术分享
#include<iostream>
#include<string.h>
#include<stdio.h>
#include<map>
#include<vector>
using namespace std;
const int maxa = 55;
#define LL long long
vector<LL> v[maxa];
map<LL, LL> mp[maxa];
const int mod = 1000000007;
LL pow[20];
int  make_numb(LL x, LL num[], LL cut[]){
    int o =0;
    LL xx = x;
    LL uu = 0;
    while(xx){
        num[o] = xx%10;
        xx /= 10;
        uu+=pow[o]*num[o];
        cut[o] = uu;
        o++;
    }
    return o;
}
LL comp(LL num[], int o, int i, int m){
   /* printf("%d\n", i);
    cout<<"===="<<endl;
    for(int i = o -1; i >= 0; i--){
        cout<<num[i];
    }puts("");*/
    LL u = 0;
    if(i<= m+1){
        for(int i = o-1; i >= 0; i--){
            u = u*10+num[i];
        }
        return u;
    }//printf("******");
    for(  int i = 0;i < o; i++){
        if(num[i] != 1)
            num[i] --;
    }
   /* cout<<"===="<<endl;
    for(int i = o -1; i >= 0; i--){
        cout<<num[i];
    }puts("");*/
    LL uu = num[o-1];
    for(int i = o-2; i >= 0; i--){
        if(num[i] == num[i+1] && num[i] == 1){
            continue;
        }
        uu = uu * 10 + num[i];
    }
    //cout<<uu<<endl;
    return uu;
}
int main(){
    int n, m;
    pow[0] = 1;
    for(int i = 1; i< 20; i++){
        pow[i] = pow[i-1]*10;
    }
    LL num1[20], cut1[20];
    LL num[20], cut[20];
    while(scanf("%d%d", &n, &m)!=EOF){
        for(int i = 0; i <= n+2; i++){
            v[i].clear();
            mp[i].clear();
        }
        if(m == 0){
            v[2].push_back(1);
            mp[2][1] = 1;
        }
        else{
            v[2].push_back(2);
            mp[2][2] = 1;
        }
        for(int i = 3; i <= n+1; i++){
            //cout<<"i=="<<i<<endl;
            for(int j = 0; j < v[i-1].size(); j ++){
                int o = make_numb(v[i-1][j], num, cut);
                int ii = min(i, m+2);

                for(int k = 0; k <= o; k++){
                //cout<<"**"<<v[i-1][j]<<endl;
                    LL u = -1;
                    if(k == 0 ){
                        if(num[k] != 1)
                            u = ii + v[i-1][j]*10;
                            //cout<<"qian"<<u<<endl;
                    }else if(k == o){
                        if(num[k-1] != 1)
                            u = v[i-1][j] + ii*pow[o];

                            //cout<<"hou"<<u<<endl;
                    }else{
                        if(num[k]!= 1 &&num[k-1] != 1){
                            u = cut[k-1] +10*(v[i-1][j] -cut[k-1])+ pow[k]*ii;
                        }
                            //cout<<"zhong"<<u<<" "<<cut[k-1]<<" "<<v[i-1][j] -cut[k-1]<<endl;
                    }
                    if(u != -1){
                        int oo = make_numb(u, num1, cut1);
                        /*for(int j = 0; j < oo; j++){
                            cout<<num1[j];
                        }printf("\n");*/
                        u = comp(num1, oo, i, m);
                        //cout<<"u == "<<u<<endl;
                        if(!mp[i][u]){
                            v[i].push_back(u);
                        }
                        mp[i][u] += mp[i-1][v[i-1][j]];
                        mp[i][u] %= mod;
                    }
                }
            }//cout<<"<<"<<endl;3
            /*for(int k = 0; k < v[i].size(); k++){
                cout<<v[i][k]<<" " <<mp[i][v[i][k]]<<endl;
            }*/
        }
        //cout<<endl;
        LL ans = 0;
        for(int i = 0; i < v[n+1].size(); i++){
            //cout<<v[n+1][i]<<" "<<mp[n+1][v[n+1][i]]<<endl;;
            ans += mp[n+1][v[n+1][i]];
            ans %= mod;
        }
        cout<<ans<<endl;
    }
}
View Code

E。所有人都没敢做,结果就是个暴力深搜,优化都不用

技术分享
#include<iostream>
#include<string.h>
#include<stdio.h>
using namespace std;
const int maxa = 30;
char str[maxa][maxa];
int mp[maxa][maxa];
int ans[maxa*maxa];
int Move[4][2] = {1, 0, -1, 0, 0, 1, 0, -1};
int o, n, m;
int anser[4] = {D,U, R, L};
int judge(int x, int y){
    if(0 <= x && x < n && 0 <= y && y < m){
        return 1;
    }return 0;
}
int dfs(int ax, int ay, int x, int y, int sum){
    if(sum == 0){
        printf("%d\n%d\n", ax, ay);
        for(int i = 0;i < o; i++){
            printf("%c", anser[ans[i]]);
        }puts("");
        return 1;
    }
    for(int i = 0; i < 4; i++){
        int vx = Move[i][0];
        int vy = Move[i][1];
        int xx = x + vx;
        int yy = y + vy;
        if(judge(xx, yy) && mp[xx][yy]==0){
            while(1){
                xx += vx;
                yy += vy;
                if(judge(xx, yy)){
                    if(mp[xx][yy]){
                        int s = sum;
                        int v = mp[xx][yy];
                        int vv = mp[xx+vx][yy+vy];
                        mp[xx][yy] = 0;
                        mp[xx+vx][yy+vy] += v-1;
                        if(judge(xx + vx, yy+ vy)){
                            sum --;
                        }else{
                            sum -= v;
                        }
                        ans[o++] = i;
                        if(dfs(ax, ay, xx, yy, sum)){
                            return 1;
                        }
                        o--;;
                        mp[xx][yy] = v;
                        mp[xx+vx][yy+vy] = vv;
                        sum = s;
                        break;
                    }
                }else
                    break;
            }
        }
    }
    return 0;
}
int main(){
    while(scanf("%d%d", &m, &n)!=EOF){
        for(int i = 0; i < n; i++){
            scanf("%s", str[i]);
        }
        int sum = 0;
        for(int i = 0;i < n; i++){
            for(int k = 0; k < m ; k++){
                if(str[i][k] ==.){
                    mp[i][k]  = 0;
                }else{
                    mp[i][k] = str[i][k] - a +1;
                }
                sum += mp[i][k];
            }
        }
        int ok = 0;
        o =  0;
        for(int i = 0; i < n; i++){
            for(int k = 0; k < m; k++){
                if(mp[i][k] == 0){
                    if(dfs(i, k, i, k, sum)){
                        ok = 1;
                        break;
                    }
                }
            }
            if(ok) break;
        }
    }
}
/*
25 25
aaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaa
.........................
.........................
aaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaa
*/
View Code

H.赤裸裸欧拉函数模板

技术分享
#include<iostream>
#include<string.h>
#include<stdio.h>
using namespace std;
const int maxa = 3000005;
int minDiv[maxa], phi[maxa];//, sum[maxa];
void genphi(){
    for(int i = 1; i < maxa; i++){
        minDiv[i] = i;
    }
    for(int i = 2; i * i < maxa; i++){
        if(minDiv[i] ==i){
            for(int j = i*i; j < maxa; j += i){
                minDiv[j] = i;
            }
        }
    }
    phi[1] = 1;
    for(int i = 2; i < maxa; i++){
        phi[i] = phi[i/minDiv[i]];
        if((i/minDiv[i]) % minDiv[i] == 0){
            phi[i] *= minDiv[i];
        }else{
            phi[i] *= minDiv[i] - 1;
        }
    }
}
int main(){
    int a, b;
    genphi();
    while(scanf("%d%d", &a, &b)!=EOF){
        long long anser = 0;
        for(int i = a; i <= b; i++){
                anser+= phi[i];
        }
        cout<<anser<<endl;
    }
}
View Code

 

F。广搜

技术分享
#include<iostream>
#include<string.h>
#include<stdio.h>
#include<queue>
using namespace std;
const int maxa = 1105;
char str[maxa][maxa];
int vis[maxa][maxa];
int n, m;
int str_x, str_y, end_x, end_y;
struct point{
    int x, y, vis;
    bool operator < (const point& a) const {
        return a.vis < vis;
    }
};
int Move[4][2] = {1, 0, -1, 0, 0, 1, 0, -1};
int judge(int x, int y){
    if(0 <= x && x < n && 0 <= y && y < m && vis[x][y] == -1){
        return 1;
    }return 0;
}
priority_queue<point>q;
int ok;/*
int dfs(int x, int y, int u){
    if(ok)return 1;
    if(judge(x,y) && str[x][y] == ‘X‘){
        vis[x][y] = u;
        q.push(point{x,y, u});
        for(int i = 0; i < 4; i++){
            dfs(x+Move[i][0], y+Move[i][1], u);
        }
    }
    if(x == end_x && y == end_y) ok = 1;

}*/
int bfs(){
    ok = 0;
    while(!q.empty())q.pop();
    memset(vis, -1, sizeof(vis));
    vis[str_x][str_y] = 0;
    q.push(point{str_x, str_y, 0});
    while(!q.empty()){
        point New = q.top(); q.pop();
        if(ok == 1)
            break;
       // printf("%d %d\n",New.x, New.y);
        for(int i = 0; i < 4; i++){
            int xx = New.x+Move[i][0];
            int yy = New.y + Move[i][1];
            if(!judge(xx, yy))continue;
            if(str[xx][yy] == .){
                vis[xx][yy] = vis[New.x][New.y]+1;
                q.push(point{xx, yy,vis[xx][yy]});
            }else{
                vis[xx][yy] = vis[New.x][New.y];
                q.push(point{xx,yy,vis[xx][yy]});
            }
        }
    }
}
int main(){
    //freopen("in.cpp", "r", stdin);
    while(scanf("%d%d", &n, &m)!=EOF){
        if(n== 0 && m == 0)break;
        for(int i = 0;i < n; i++){
            scanf("%s", &str[i]);
        }
        scanf("%d%d%d%d", &str_x, &str_y, &end_x, &end_y);
        str_x--,str_y--,end_x--,end_y--;
        bfs();
        printf("%d\n", vis[end_x][end_y]);
    }return 0;
}
View Code

大二第一次东北团队训练赛

原文:http://www.cnblogs.com/icodefive/p/4360809.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!