题解

1309 条题解

  • 0
    @ 2016-12-11 18:52:57

    这道题实际上是一道最短路的模型题。我们只需要构造一个有三个顶点的无向图,1和2之间有一条边权为a的边,2和3之间有一条边权为b的边,而1和3之间有一条边权为maxlongint的边,那么答案就是1到3的最短路

  • 0
    @ 2016-12-11 18:52:46

    (此代码包括高精度运算,仅供参考)

    (变量在下面!!!)

    [hr ]

    (
    begin
    repeat
    inc(l1);
    read(ch[l1]);
    until eoln;
    for i:=1 to l1 do a[i]:=ord(ch[l1-i+1])-48;
    readln;
    repeat
    inc(l2);
    read(ch[l2]);
    until eoln;
    for i:=1 to l2 do b[i]:=ord(ch[l2-i+1])-48;
    if l1<l2 then l1:=l2;//加法运算要进行max(l1,l2)次,这里用l1保存运算次数
    for i:=1 to l1 do
    begin
    inc(c[i],a[i]+b[i]);//还要加上可能有的从低位进上来的值
    if c[i]>=10 then//进位
    begin
    dec(c[i],10);
    inc(c[i+1]);
    end;
    end;
    if c[l1+1]>0 then inc(l1);//检测最高位是否进位
    for i:=l1 downto 1 do write(c[i]);
    end.
    var i,l1,l2:longint;
    a,b,c:array [1..502] of longint;
    ch:array [1..502] of char;)

  • 0
    @ 2016-12-11 18:50:55

    最小生成树最好了

    #include <cstdio>
    #include <algorithm>
    #define INF 2140000000
    using namespace std;
    struct tree{int x,y,t;}a[10];
    bool cmp(const tree&a,const tree&b){return a.t<b.t;}
    int f[11],i,j,k,n,m,x,y,t,ans;
    int root(int x){if (f[x]==x) return x;f[x]=root(f[x]);return f[x];}
    int main(){
    for (i=1;i<=10;i++) f[i]=i;
    for (i=1;i<=2;i++){
    scanf("%d",&a[i].t);
    a[i].x=i+1;a[i].y=1;k++;
    }
    a[++k].x=1;a[k].y=3,a[k].t=INF;
    sort(a+1,a+1+k,cmp);
    for (i=1;i<=k;i++){
    // printf("%d %d %d %d\n",k,a[i].x,a[i].y,a[i].t);
    x=root(a[i].x);y=root(a[i].y);
    if (x!=y) f[x]=y,ans+=a[i].t;
    }
    printf("%d\n",ans);
    }

  • 0
    @ 2016-12-11 18:50:33

    Dijkstra+STL的优先队列优化。48ms.

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <cctype>
    #include <climits>
    #include <algorithm>
    #include <map>
    #include <queue>
    #include <vector>
    #include <ctime>
    #include <string>
    #include <cstring>
    using namespace std;
    const int N=405;
    struct Edge {
    int v,w;
    };
    vector<Edge> edge[N*N];
    int n;
    int dis[N*N];
    bool vis[N*N];
    struct cmp {
    bool operator()(int a,int b) {
    return dis[a]>dis[b];
    }
    };
    int Dijkstra(int start,int end)
    {
    priority_queue<int,vector<int>,cmp> dijQue;
    memset(dis,-1,sizeof(dis));
    memset(vis,0,sizeof(vis));
    dijQue.push(start);
    dis[start]=0;
    while(!dijQue.empty()) {
    int u=dijQue.top();
    dijQue.pop();
    vis[u]=0;
    if(u==end)
    break;
    for(int i=0; i<edge[u].size(); i++) {
    int v=edge[u][i].v;
    if(dis[v]==-1 || dis[v]>dis[u]+edge[u][i].w) {
    dis[v]=dis[u]+edge[u][i].w;
    if(!vis[v]) {
    vis[v]=true;
    dijQue.push(v);
    }
    }
    }
    }
    return dis[end];
    }
    int main()
    {
    int a,b;
    scanf("%d%d",&a,&b);
    Edge Qpush;

    Qpush.v=1;
    Qpush.w=a;
    edge[0].push_back(Qpush);

    Qpush.v=2;
    Qpush.w=b;
    edge[1].push_back(Qpush);

    printf("%d",Dijkstra(0,2));
    return 0;
    }

  • 0
    @ 2016-12-11 18:50:14

    5ms , 1371kb

    线段树走起

    附上在下65行线段树代码

    #include<cstdio>
    #include<algorithm>
    #include<cstdlib>
    #include<cmath>
    #include<cstring>
    #include<iostream>
    using namespace std;
    struct node{
    int val,l,r;
    };
    node t[5];
    int a[5],f[5];
    int n,m;
    void init(){
    for(int i=1;i<=2;i++){
    scanf("%d",&a[i]);
    }
    }
    void build(int l,int r,int node){//这是棵树
    t[node].l=l;t[node].r=r;t[node].val=0;
    if(l==r){
    f[l]=node;
    t[node].val=a[l];
    return;
    }
    int mid=(l+r)>>1;
    build(l,mid,node*2);
    build(mid+1,r,node*2+1);
    t[node].val=t[node*2].val+t[node*2+1].val;
    }
    void update(int node){
    if(node==1)return;
    int fa=node>>1;
    t[fa].val=t[fa*2].val+t[fa*2+1].val;
    update(fa);
    }
    int find(int l,int r,int node){
    if(t[node].l==l&&t[node].r==r){
    return t[node].val;
    }
    int sum=0;
    int lc=node*2;int rc=lc+1;
    if(t[lc].r>=l){
    if(t[lc].r>=r){
    sum+=find(l,r,lc);
    }
    else{
    sum+=find(l,t[lc].r,lc);
    }
    }
    if(t[rc].l<=r){
    if(t[rc].l<=l){
    sum+=find(l,r,rc);
    }
    else{
    sum+=find(t[rc].l,r,rc);
    }
    }
    return sum;
    }
    int main(){
    init();
    build(1,2,1);
    printf("%d",find(1,2,1));
    }

  • 0
    @ 2016-12-11 18:49:50

    见各位大神纷纷以流与树解题,本人不才,在此附上伪深搜算法;

    #include<iostream>
    #include<stdio.h>
    using namespace std;
    int d[3];
    int ans;
    void dfs(int x)
    {

    ans+=d[x];
    if(x==2)
    {
    printf("%d",ans);
    return ;
    }
    dfs(x+1);
    }
    int main()
    {
    for(int i=1;i<=2;i++)
    {
    scanf("%d",&d[i]);
    }
    dfs(1);
    return 0;
    }

  • 0
    @ 2016-12-11 18:48:51

    表示我稍微加上了一个读入和输出优化。。。。

    为什么要占坑呢,主要是发一下读入输出优化的代码

    顺便给新生们传授一下c++超快的读入输出方法。。。

    一般来说,c++有三种读入方式 scanf cin 以及读入优化。。。

    cin 在加上ios优化之前是很慢的 scanf其次 读入优化(read)最快

    以下是我做的测试数据

    当读入从1开始到10^7的数列数据时:

    cin耗时6.02s,scanf耗时2.23s,read只耗时0.58s

    同理 cont>scanf>输出优化

    对付大数据的题目这是可以用的(前提是数据输入输出都是纯数据,没有符号【包括英文字母】)

    新生可以先不用弄懂实现原理,直接背就行了。这些优化NOIP是可以用的。

    下面是代码
    */

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    using namespace std;
    int read(){
    int out=0,fh=1;
    char cc=getchar();
    if (cc=='-') fh=-1;
    while (cc>'9'||cc<'0') cc=getchar();
    while (cc>='0'&&cc<='9') {out=out*10+cc-'0';cc=getchar();}
    return out*fh;
    }
    void write(int x)

    {

    if (x==0){
    putchar('0');
    return;
    }
    int num = 0; char c[15];
    while(x) c[++num] = (x%10)+48, x /= 10;
    while(num) putchar(c[num--]);
    putchar(' ');
    }
    int main(){
    write(read()+read());
    return 0;
    }

  • 0
    @ 2016-12-11 18:48:25

    一题很棒的模拟题,可以模拟人工运算的方法。

    #include <iostream>
    #include <cmath>
    using namespace std;
    int fu=1,f=1,a,b,c=0;
    int main()
    {
    cin>>a>>b;
    if(a<0&&b>0)fu=2;
    if(a>0&&b<0)fu=3;
    if(a<0&&b<0)f=-1;
    if(a==0){cout<<b;return 0;}
    if(b==0){cout<<a;return 0;}
    a=abs(a);
    b=abs(b);
    if(a>b&&fu==3)f=1;
    if(b>a&&fu==3)f=-1;
    if(b>a&&fu==2)f=1;
    if(b<a&&fu==2)f=-1;
    if(fu==1)c=a+b;
    if(fu>1)c=max(a,b)-min(a,b);
    c*=f;
    cout<<c;
    return 0;
    }

  • 0
    @ 2016-12-11 18:48:11

    明显的字典树

    以每个数字建立字典树

    建立一次查询一次

    spj正负 下面上代码

    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    using namespace std;
    struct node{
    int str[26];
    int sum;
    }s[1000];
    char str1[100];
    int t=0,tot=0,ss=0;
    bool f1;
    void built()
    {
    t=0;
    for(int i=0;i<strlen(str1);i++)
    {
    if(str1[i]=='-'){
    f1=true;continue;
    }
    if(!s[t].str[str1[i]-'0'])
    s[t].str[str1[i]-'0']=++tot;
    t=s[t].str[str1[i]-'0'];
    s[t].sum=str1[i]-'0';
    }
    }
    int query()
    {
    int t=0;int s1=0;
    for(int i=0;i<strlen(str1);i++)
    {
    if(str1[i]=='-') continue;
    if(!s[t].str[str1[i]-'0']) return s1;
    t=s[t].str[str1[i]-'0'];
    s1=s1*10+s[t].sum;
    }
    return s1;
    }
    int main()
    {

    for(int i=1;i<=2;i++)
    {
    f1=false;
    scanf("%s",str1);
    built();
    if(f1)
    ss-=query();
    else ss+=query();
    }
    printf("%d",ss);
    return 0;

    }

  • 0
    @ 2016-12-11 18:47:18

    各位大神都用网络流啊 最短路啊解这道题,那么既然是可以求最短路,为什么不可以从树上跑呢?

    怀着这种想法,我冥思苦想(划掉),发现,###我可以用LCA做这道题啊~

    然而鄙人不才,什么Tarjan啊ST表啊都不会,只会用一个倍增来求LCA,所以权当抛砖引玉吧。

    不过我估计应该没什么想学LCA的来这道题看LCA题解吧。所以多半是写着玩~~

    先说说思路(这还用说?):

    建一个有三个节点的树,1为树根,2 3分别是左右儿子。

    其中1 2之间的距离为a,2 3之间的距离为b,然后求1 2的LCA,和分别到LCA的距离,加起来就是1->3的最短路

    其实就是题目中所求的a+b了

    好吧闲话不说 上代码了(多半是个LCA的板子了):

    #include<cstdio> //头文件
    #define NI 2

    //从来不喜欢算log所以一般用常数 不知道算不算坏习惯 因为3个节点 所以log3(当然以2为底)上取整得2
    struct edge
    {
    int to,next,data; //分别表示边的终点,下一条边的编号和边的权值
    }e[30]; //邻接表,点少边少开30是为了浪啊
    int v[10],d[10],lca[10][NI+1],f[10][NI+1],tot=0; //数组开到10依然为了浪
    //数组还解释嘛,v表示第一条边在邻接表中的编号,d是深度,lca[x][i]表示x向上跳2^i的节点,f[x][i]表示x向上跳2^i的距离和
    void build(int x,int y,int z) //建边
    {
    e[++tot].to=y; e[tot].data=z; e[tot].next=v[x]; v[x]=tot;
    e[++tot].to=x; e[tot].data=z; e[tot].next=v[y]; v[y]=tot;
    }
    void dfs(int x) //递归建树
    {
    for(int i=1;i<=NI;i++) //懒,所以常数懒得优化
    f[x][i]=f[x][i-1]+f[lca[x][i-1]][i-1],
    lca[x][i]=lca[lca[x][i-1]][i-1]; //建树的同时进行预处理
    for(int i=v[x];i;i=e[i].next) //遍历每个连接的点
    {
    int y=e[i].to;
    if(lca[x][0]==y) continue;
    lca[y][0]=x; //小技巧:lca[x][0]即为x的父亲~~(向上跳2^0=1不就是父节点嘛)
    f[y][0]=e[i].data;
    d[y]=d[x]+1;
    dfs(y); //再以这个节点为根建子树【这里真的用得到嘛??】
    }
    }
    int ask(int x,int y) //询问,也是关键
    {

    if(d[x]<d[y]) {int t=x;x=y;y=t;} //把x搞成深的点
    int k=d[x]-d[y],ans=0;
    for(int i=0;i<=NI;i++)
    if(k&(1<<i)) //若能跳就把x跳一跳
    ans+=f[x][i], //更新信息
    x=lca[x][i];
    for(int i=NI;i>=0;i--) //不知道能不能正着循环,好像倒着优,反正记得倒着就好了
    if(lca[x][i]!=lca[y][i]) //如果x跳2^i和y跳2^j没跳到一起就让他们跳
    ans+=f[x][i]+f[y][i],
    x=lca[x][i],y=lca[y][i];
    return ans+f[x][0]+f[y][0]; //跳到LCA上去(每步跳的时候都要更新信息,而且要在跳之前更新信息哦~)
    }
    int main()
    {
    int a,b;
    scanf("%d%d",&a,&b);
    build(1,2,a);
    build(1,3,b); //分别建1 2、1 3之间的边
    dfs(1); //以1为根建树
    printf("%d",ask(2,3)); //求解2 3到它们的LCA的距离和并输出
    }

  • 0
    @ 2016-12-11 18:46:36

    看也有位运算,用递归做的,我就贴个非递归的吧。。。

    #include <cstdio>
    int m, n;
    int main()
    {
    scanf("%d%d", &m, &n);
    int u = m & n;
    int v = m ^ n;
    while (u) {
    int s = v;
    int t = u << 1;
    u = s & t;
    v = s ^ t;
    }
    printf("%d\n", v);
    }

  • 0
    @ 2016-12-11 18:45:34

    使用了fread和fwrite输入输出优化,速度还挺快

    #include <cstdio>
    const size_t fSize = 1 << 15;
    char iFile[fSize], *iP = iFile, oFile[fSize], *oP = oFile;
    inline char readchar() {
    if (*iP && iP - iFile < fSize) { char t = *iP; iP++; return t; } else return EOF;
    }
    template<typename T> inline void readint(T &x) {
    x = 0; char c; bool neg = 0;
    while ((c = readchar()) < '0' || c > '9') if (c == '-') neg = !neg;
    while (c >= '0' && c <= '9')
    x = x * 10 + (c ^ 48), c = readchar();
    x = neg ? -x : x;
    }
    inline void writechar(const char &c) { *oP = c, ++oP; }
    template<typename T> inline void _writeint(const T &x) {
    if (!x)
    return;
    _writeint(x / 10);
    writechar(x % 10 ^ 48);
    }
    template<typename T> inline void writeint(T x, const char &c) {
    if (x < 0) {
    writechar('-');
    x = -x;
    }
    if (!x) {
    writechar('0');
    return;
    }
    _writeint(x);
    writechar(c);
    }
    int main() {
    fread(iFile, 1, fSize, stdin);
    int a, b;
    readint(a); readint(b);
    writeint(a + b, '\n');
    fwrite(oFile, 1, oP - oFile, stdout);
    return 0;
    }

  • 0
    @ 2016-12-11 18:45:02

    通过100纪念

  • 0
    @ 2016-12-04 15:03:40

    #include <iostream>
    using namespace std;
    int main()
    {
    int a, b;
    cin >> a >> b;
    cout << a + b << endl;
    return 0;
    }

  • 0
    @ 2016-12-04 13:54:03

    我来告诉你们什么叫做人品(亮点在程序)
    测试数据 #0: Accepted, time = 0 ms, mem = 804 KiB, score = 10

    测试数据 #1: Accepted, time = 0 ms, mem = 812 KiB, score = 10

    测试数据 #2: Accepted, time = 0 ms, mem = 808 KiB, score = 10

    测试数据 #3: Accepted, time = 0 ms, mem = 804 KiB, score = 10

    测试数据 #4: Accepted, time = 0 ms, mem = 812 KiB, score = 10

    测试数据 #5: Accepted, time = 0 ms, mem = 812 KiB, score = 10

    测试数据 #6: Accepted, time = 0 ms, mem = 808 KiB, score = 10

    测试数据 #7: Accepted, time = 0 ms, mem = 812 KiB, score = 10

    测试数据 #8: Accepted, time = 0 ms, mem = 808 KiB, score = 10

    测试数据 #9: Accepted, time = 0 ms, mem = 808 KiB, score = 10

    var a,b:longint;
    begin
    randomize;
    readln(a,b);
    writeln(a+b+random(50));
    end.

  • 0
    @ 2016-10-01 20:19:51

    Python题解
    import sys
    a , b= map(int,sys.stdin.readline().split())
    print a + b

  • 0
    @ 2016-09-21 22:14:00

  • 0
    @ 2016-09-19 13:02:06

    无聊写的A+B问题。。。。
    c++
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<cstdio>
    #define INF 0x7fffffff
    using namespace std;
    int a,b,cnt;
    int ans[10],h[10],head[10],father[10],bit[10],mp[3][3],w[3],c[3],f[3];
    struct data1{int to,next,v;}e[10];
    struct data2{int x,y,v;}ed[10];
    struct data3{int l,r,sum;}tr[10];
    void insert(int u,int v,int w)
    {
    cnt++;
    e[cnt].to=v;
    e[cnt].v=w;
    e[cnt].next=head[u];
    head[u]=cnt;
    }
    bool bfs()
    {
    int q[10],t=0,w=1,i,now;
    memset(h,-1,sizeof(h));
    q[0]=h[0]=0;
    while(t<w)
    {
    now=q[t];t++;
    i=head[now];
    while(i)
    {
    if(e[i].v&&h[e[i].to]==-1)
    {q[w++]=e[i].to;h[e[i].to]=h[now]+1;}
    i=e[i].next;
    }
    }
    if(h[3]==-1)return 0;
    return 1;
    }
    int dfs(int x,int f)
    {
    if(x==3)return f;
    int w,used=0,i=head[x];
    while(i)
    {
    if(e[i].v&&h[e[i].to]==h[x]+1)
    {
    w=f-used;
    w=dfs(e[i].to,min(e[i].v,w));
    e[i].v-=w;
    e[i^1].v+=w;
    used+=w;
    if(used==f)return f;
    }
    i=e[i].next;
    }
    if(!used)h[x]=-1;
    return used;
    }
    void dinic()
    {
    cnt=1;
    memset(head,0,sizeof(head));
    insert(0,1,a);insert(1,0,0);
    insert(1,3,INF);insert(3,1,0);
    insert(0,2,b);insert(2,0,0);
    insert(2,3,INF);insert(3,2,0);
    while(bfs()){ans[1]+=dfs(0,INF);}
    }
    void spfa()
    {
    cnt=0;
    memset(head,0,sizeof(head));
    insert(0,1,a);
    insert(1,2,b);
    int dis[3],q[10],t=0,w=1,i,now;
    bool inq[10];
    memset(dis,127/3,sizeof(dis));
    memset(inq,0,sizeof(inq));
    q[0]=dis[0]=0;inq[0]=1;
    while(t<w)
    {
    now=q[t];t++;
    i=head[now];
    while(i)
    {
    if(e[i].v+dis[now]<dis[e[i].to])
    {
    dis[e[i].to]=e[i].v+dis[now];
    if(!inq[e[i].to])
    {
    inq[e[i].to]=1;
    q[w++]=e[i].to;
    }
    }
    i=e[i].next;
    }
    inq[now]=0;
    }
    ans[2]=dis[2];
    }
    void floyd()
    {
    memset(mp,127/3,sizeof(mp));
    mp[1][2]=a;mp[2][3]=b;
    for(int k=1;k<=3;k++)
    for(int i=1;i<=3;i++)
    for(int j=1;j<=3;j++)
    mp[i][j]=min(mp[i][j],mp[i][k]+mp[k][j]);
    ans[3]=mp[1][3];
    }
    void seg_build(int k,int s,int t)
    {
    tr[k].l=s;tr[k].r=t;
    if(s==t)return;
    int mid=(s+t)>>1;
    seg_build(k<<1,s,mid);
    seg_build(k<<1|1,mid+1,t);
    tr[k].sum=tr[k<<1].sum+tr[k<<1|1].sum;
    }
    void seg_change(int k,int x,int y)
    {
    int l=tr[k].l,r=tr[k].r;
    tr[k].sum+=y;
    if(l==r)return;
    int mid=(l+r)>>1;
    if(y<=mid)seg_change(k<<1,x,y);
    else seg_change(k<<1|1,x,y);
    }
    int seg_ask(int k,int x,int y)
    {
    int l=tr[k].l,r=tr[k].r;
    if(x==l&&y==r)return tr[k].sum;
    int mid=(l+r)>>1;
    if(mid>=y)return seg_ask(k<<1,x,y);
    else if(mid<x)return seg_ask(k<<1|1,x,y);
    else return seg_ask(k<<1,x,mid)+seg_ask(k<<1|1,mid+1,y);
    }
    void segtree()
    {
    seg_build(1,1,2);
    seg_change(1,1,a);
    seg_change(1,1,b);
    ans[4]=seg_ask(1,1,2);
    }
    int lowbit(int x){return x&(-x);}
    int bit_ask(int x)
    {
    int s=0;
    while(x)
    {
    s+=bit[x];
    x-=lowbit(x);
    }
    return s;
    }
    void bit_change(int x,int y)
    {
    while(x<=2)
    {
    bit[x]+=y;
    x+=lowbit(x);
    }
    }
    void bitree()
    {
    bit_change(1,a);
    bit_change(2,b);
    ans[5]=bit_ask(2);
    }
    int find(int x){return x==find(x)?x:father[x]=find(father[x]);}
    bool cmp(data2 a,data2 b){return a.v<b.v;}
    void kruskal()
    {
    ed[1].x=0;ed[1].y=1;ed[1].v=a;
    ed[2].x=1;ed[2].y=2;ed[2].v=b;
    sort(ed+1,ed+3,cmp);
    for(int i=0;i<=2;i++)father[i]=i;
    for(int i=1;i<=2;i++)
    {
    int x=father[ed[i].x],y=father[ed[i].y];
    if(x!=y){father[x]=y;ans[6]+=ed[i].v;}
    }
    }
    void dp()
    {
    w[1]=w[2]=1;
    c[1]=a;c[2]=b;
    for(int i=1;i<=2;i++)
    for(int v=2;v>=w[i];v--)
    f[v]=max(f[v],f[v-w[i]]+c[i]);
    ans[7]=f[2];
    }
    int main()
    {
    scanf("%d%d",&a,&b);
    dinic();//cout<<ans[1]<<endl;
    spfa();//cout<<ans[2]<<endl;
    floyd();//cout<<ans[3]<<endl;
    segtree();//cout<<ans[4]<<endl;
    bitree();//cout<<ans[5]<<endl;
    kruskal();//cout<<ans[6]<<endl;
    dp();//cout<<ans[7]<<endl;
    for(int i=1;i<=7;i++)ans[0]+=ans[i];
    ans[0]/=7;
    printf("%d",ans[0]);
    return 0;
    }

    23333333333333333333333333333333333333333333333333333

    ---转自黄学长

  • 0
    @ 2016-09-17 11:51:34
    #include<cstdlib>
    #include<cstdio>
    int main(int a,int b,int k)
    {
        if (k) scanf("%d%d",&a,&b);
        printf("%d",b==0?a:main(a^b,(a&b)<<1,0));
        exit(0);
    }
    

    233333333333333333

  • 0
    @ 2016-09-16 21:03:13

    #include<stdio.h>
    int main(){
    int a,b;
    scanf("%d%d",&a,&b);
    printf("%d",a+b);
    return 0;
    }

信息

ID
1000
难度
9
分类
(无)
标签
(无)
递交数
73489
已通过
28184
通过率
38%
被复制
200