北邮新生排位赛9解题报告

时间限制 1000 ms 内存限制 65536 KB

题目描述

You are givin an array of integers, and you are to figure out the sum of differences between each pair of integers belonging to the array. SEE THE HINT FOR MORE INFORMATION.

输入格式

There are multiple test cases. The first line contains an integer n(n<=1e5), size of the array. The second line contains n integers, ai(|ai|<=100000), the array.

输出格式

For each case, output one line, the answer.

输入样例

4
1 1 2 2

输出样例

4

hint
for the test case the answer is abs(1-1)+abs(1-2)+abs(1-2)+abs(1-2)+abs(1-2)+abs(2-2)=4

#include <cstdio>
#include <algorithm>
using namespace std;
long long sum[100001];
long long a[100001];
int  main(){
    int n;
    while(scanf("%d",&n)==1){
        for(int i=0;i<n;i++){\
            scanf("%lld",a+i);
        }
        sort(a,a+n);
        sum[0]=a[0];
        for(int i=1;i<n;i++){
            sum[i]=sum[i-1]+a[i];
        }
        long long ans=0;
        for(int i=1;i<n;i++){
            ans+=a[i]*i-sum[i-1];
        }
        printf("%lld\n",ans);
    }
    return 0;
}
//只是卡在lld

时间限制 1000 ms 内存限制 65536 KB

题目描述

Mays王国的女王大人每天过着自由自在的生活,她最大的乐趣就是给邻国的帅气王子写信。但是最近,Mays王国的叔叔们变得很无聊,他们知道女王大人每次都把信委托给皇家小妹妹快递公司的小妹妹们,于是叔叔们给每一条路都设立了路障,只有小妹妹们给他们表演节目才会让小妹妹们过去。
在每一个路障,都有不同数量的叔叔,只有表演的小妹妹的数量不少与叔叔的数量的时候叔叔才会放她们过去。
可是七夕快要到了,Masy王国的每一个人都在给自己的情人写信。
Mays王国由n个地区组成,一些双向的道路连接着这些地区。注意两个地区之间可能有多条道路相通。
无聊的单身的beegerous已经算出了从一点到另一点送信最少需要的小妹妹的数量,为了表达对世界的不满,他脑补出了小妹妹们给任意两个点之间送信的画面,这样她们一共需要送n*(n-1)次信!如果所有的信件必须同一时间发出,这样每一次快递都需要由不同的小妹妹们来送!这样就会有好多好多小妹妹在Mays王国的道路上忙碌了。
请问,按上述脑补情形,皇家小妹妹快递公司一共需要派出多少小妹妹。

输入格式

输入第一行为数据组数T(T<=10),接下来T组数据,每组第一行为n,m,,2<=n<=10000,1<=m<=100000,表示Mays王国的道路由n个节点组成,接下来m行,每行一组u,v,c表示连接节点u,v的一条无向道路,且路障上有c个叔叔,1<=u,v<=n,0<=c<=100。
输入保证任意两点之间可达。

输出格式

每组数据输出一个数字,表示小妹妹快递公司最少需要派出的小妹妹数量。

输入样例

1
3 3
1 2 1
2 3 1
1 3 3

输出样例

6

hint:
9种送快递的方式及花费为:
1 --> 2:  1
1 --> 3:  1
2 --> 1:  1
2 --> 3:  1
3 --> 1:  1
3 --> 2:  1
答案为6
这道题并查集我用了断言,断言最后集合的数目为n结果反而错了??
#include <cstdio>
#include <assert.h>
#include <algorithm>
using namespace std;
const int maxn=10011;
const int maxm=100011;
struct edge{
    int f,t,c;
}e[maxm];
int par[maxn];
int num[maxn];
int  fp(int i){
    if(par[i]==i)return i;
    return par[i]=fp(par[i]);
}
bool same(int a,int b){
    return (fp(a)==fp(b));
}
bool uni(int a,int b){
    if(same(a,b))return false;
    num[fp(a)]+=num[fp(b)];
    num[fp(b)]=0;
    par[fp(b)]=par[fp(a)];
    return true;
}
bool cmp(edge e1,edge e2){
    if(e1.c<e2.c){return true;}
    return false;
}
int main(){
    long long ans;
    int n,m;
    int t;
    scanf("%d",&t);
    while(t--){
        scanf("%d%d",&n,&m);
        ans=0;
        for(int i=0;i<m;i++){
            scanf("%d%d%d",&(e[i].f),&(e[i].t),&(e[i].c));
        }
        for(int i=1;i<=n;i++){par[i]=i;num[i]=1;}
        sort(e,e+m,cmp);
        bool fl=false;
        for(int i=0;i<m;i++){
            if(!same(e[i].t,e[i].f)){
                if(e[i].c==0)e[i].c=1;
                ans+=num[fp(e[i].f)]*num[fp(e[i].t)]*e[i].c;
                uni(e[i].f,e[i].t);
                if(num[fp(e[i].t)]==n){
                    fl=true;
                    break;
                }
            }
        }
        if(num[fp(1)]==n)fl=true;
        //assert(fl);
ans*=2;
        printf("%lld\n",ans);
    }
    return 0;
}

时间限制 6000 ms 内存限制 65536 KB

题目描述

Mays王国的女王大人每天过着自由自在的生活,她最大的乐趣就是给邻国的帅气王子写信。而负责给她送信的就是皇家小妹妹快递公司。
今天负责给女王大人送信的是一个新来的小妹妹,她非常好奇女王大人的信,于是悄悄的把它拆开来看了!但是机智的女王大人早就想到了会有这种情况发生,她和邻国帅气王子的信都是加密过的~
小妹妹研究了一路,她感觉,里面重复比较多的内容应该是有用信息。为了安慰自己的智商,小妹妹希望找到信的一个最长连续的子串,这个子串出现2次或以上。为了能找到的子串尽可能长,小妹妹认为即便出现的2次有一部分重叠也是可以的。

输入格式

输入第一行为数据组数T(T<=10),每组一行字符串str,str中只包含小写字母,且长度不超过2000。

 

输出格式

每组答案输出一行。

输入样例

2
aabbaabbaa
abcde

输出样例

6
0
据说应该用hash,不过学到新姿势kmp算法
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxm=2001;
int next[maxm];
int bufflen;
int mans;
char buff[2015];
void getnext(int s){
    int j=s-1;
    int i=s;
    next[i]=j;
    while(i<bufflen){
        if(j==s-1||buff[i]==buff[j]){
            i++;
            j++;
            next[i]=j;
        }
        else {j=next[j];}
    }
}
int kmp(int s){
    int ans=0;
    int bs=s;
    int ins=s+1;
    while(ins<bufflen){
        if(bs==s-1||buff[ins]==buff[bs]){
            bs++;
            ins++;
            ans=max(ans,bs-s);
        }
        else{
            bs=next[bs]<s?s-1:next[bs];
        }
    }
    return ans;
}
int main(){
    int t;
    scanf("%d",&t);
    while(t--){
        scanf("%s",buff);
        bufflen=strlen(buff);
        mans=0;
        for(int i=0;i<bufflen;i++){
            getnext(i);
            mans=max(mans,kmp(i));
        }
        printf("%d\n",mans);
    }
    return 0;
}

D:
时间限制 1000 ms 内存限制 65536 KB

题目描述

大家都知道,学校里有很多路在修,修路需要砖块。这一天,Mr.F来到集训队,找学妹去帮忙搬砖块。善良的学长们不忍心让学妹劳动,就争先恐后的帮助学妹搬砖。于是聪明的学妹说,我出一个题,谁答出来谁就能帮我搬砖。
把学校要铺的地面看成是n*m的方格,每一块砖的大小是1*2,学妹想知道有多少种方法可以把这块地铺满。注意地上有可能会有花花草草,有爱心的学妹不忍心砖块把它们压死,所以这些点是不可以铺砖块的。

输入格式

输入多组数据,数据组数不超过20组。每组第一行为三个整数n, m, k,(1<=n, m<=10),k<=n*m,分别代表地面的长宽,以及花花草草的数量。接下来k行,每行一组x,y,表示花花草草的坐标。详细方向见样例。

输出格式

每组输出一个数,即最后的方案数。由于输出会很大,请输出答案mod 1000000007(10^9+7)。

输入样例

3 1 1
2 0

3 1 0

输出样例

1
0

hint:
第一组样例所示地面为:
.
.
*
其中‘.‘表示空地,’*‘表示花花草草,一种方案可以铺满。
诸位大神带跑了榜啊,白书上有模板

坑爹坑爹。问题如下:这是个递归过程的话那么就可以判断这一行填满的时候上一行一定已经被填满了,直接取就可以了,不管是从上往下取还是从下往上取,但是要从状态本身推向下一个状态则不知道下一个状态会是什么
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
int dp[2][1<<11];
const int mod= 1000000007;
int n,m,k;
bool cant[10][10];
int calc(){
    dp[0][0]=1;
    int * cur=dp[0];int * nxt=dp[1];
    for(int i=n-1;i>=0;i--){
        for(int j=m-1;j>=0;j--){
            for(int sta=(1<<m)-1;sta>=0;sta--){
                if(cant[i][j]||sta&(1<<j)){
                    nxt[sta]=cur[sta&~(1<<j)];
                }
                else {
                    nxt[sta]=0;
                    if((i+1<n)&&(!cant[i+1][j])){
                        nxt[sta]=cur[sta|(1<<j)];
                    }
                    if(j+1<m&&(!cant[i][j+1])&& !(sta&(1<<(j+1))) ){
                        nxt[sta]=(cur[sta|(1<<(j+1))]+nxt[sta])%mod;
                    }
                }
            }
            swap(cur,nxt);
        }
    }
    printf("%d\n",cur[0]);
    return cur[0];
}
int main(){
    while(scanf("%d%d%d",&n,&m,&k)==3){
        while(k--){
            int tx,ty;
            scanf("%d%d",&tx,&ty);
            cant[tx][ty]=true;
        }
        calc();
        memset(dp,0,sizeof(dp));
        memset(cant,0,sizeof(cant));
    }
    return 0;
}


posted @ 2014-08-04 10:00  雪溯  阅读(285)  评论(0编辑  收藏  举报