题解

1323 条题解

  • 0
    @ 2016-12-14 11:58:17

    高精度的代码,其实是比较暴力的高精,但是因为它小于等于2^15-1,所以没什么关系。
    我是通用性的高精度代码,所以数组开了10000.接下来就是——代码!

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    using namespace std;
    char a1[10000],b1[10000];int a[10000],b[10000],c[10000],x=0,lena,lenb,lenc=1,i;
    int main()
    {
    scanf("%s",a1);scanf("%s",b1);lena=strlen(a1);lenb=strlen(b1);
    for(i=0;i<=lena-1;i++) a[lena-i]=a1[i]-'0';
    for(i=0;i<=lenb-1;i++) b[lenb-i]=b1[i]-'0';
    while(lenc<=lena||lenc<=lenb)
    {
    c[lenc]=a[lenc]+b[lenc]+x;
    x=c[lenc]/10;
    c[lenc]%=10;
    lenc++;
    }
    if(0==(c[lenc]=x)) lenc--;
    for(i=lenc;i>=1;i--) cout<<c[i];return 0;
    }

    祝大家刷题快乐,从这里开始。

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

    以下题解不必去理解,为搜集到的大牛解法,当然,也有自己写的

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

    你们怎么能水过这题呢?

    这么好的一道网络流的题,应当用高标预流推进

    [/color][codec ]#include<bits/stdc++.h>
    using namespace std;
    #define set(x) Set(x)
    #define REP(i,j,k) for (int i=(j),_end_=(k);i<=_end_;++i)
    #define DREP(i,j,k) for (int i=(j),_start_=(k);i>=_start_;--i)
    #define debug(...) fprintf(stderr,__VA_ARGS__)
    #define mp make_pair
    #define x first
    #define y second
    #define pb push_back
    #define SZ(x) (int((x).size()-1))
    #define ALL(x) ((x).begin()+1),(x).end()
    template<typename T> inline bool chkmin(T &a,const T &b){ return a > b ? a = b, 1 : 0; }
    template<typename T> inline bool chkmax(T &a,const T &b){ return a < b ? a = b, 1 : 0; }
    typedef long long LL;
    typedef pair<int,int> node;
    const int dmax=1010,oo=0x3f3f3f3f;
    int n,m;
    int a[dmax][dmax] , ans;
    int d[dmax],e[dmax];
    priority_queue <node> q;
    inline bool operator >(node a,node b){ return a.y>b.y; }
    bool p[dmax];
    void Set(int x){ p[x]=1; }
    void unset(int x){ p[x]=0; }
    bool check(int x){ return x!=1 && x!=n && !p[x] && e[x]>0; }
    void preflow(){
    e[1]=oo;
    d[1]=n-1;
    q.push(mp(1,n-1));
    set(1);
    while (!q.empty()){
    bool flag=1;
    int k=q.top().x;
    q.pop(),unset(k);
    DREP(i,n,1)
    if ((d[k]==d[i]+1 || k==1) && a[k][i]>0){
    flag=0;
    int t=min(a[k][i],e[k]);
    e[k]-=t;
    a[k][i]-=t;
    e[i]+=t;
    a[i][k]+=t;
    if (check(i)){
    q.push(mp(i,d[i]));
    set(i);
    }
    if (e[k]==0) break;
    }
    if (flag){
    d[k]=oo;
    REP(i,1,n)
    if (a[k][i]>0)
    chkmin(d[k],d[i]+1);
    }
    if (check(k)){
    q.push(mp(k,d[k]));
    set(k);
    }
    }
    ans=e[n];
    }
    int main(){
    n = 2, m = 2;
    int x, y;
    scanf("%d%d", &x, &y);
    a[1][2] += x + y;
    preflow();
    printf("%d\n",ans);
    return 0;
    }
    [/codec ]

  • 0
    @ 2016-12-11 18:53:19

    program problem;
    var
    en,et,ec,eu,ep,ex:Array[0..250000] of longint;
    dis:array[0..1000] of longint;
    v:array[0..1000] of boolean;
    i,j,k,n,m,w,cost,l:longint;
    a,b,ans,left,right:longint;
    function min(a,b:longint):longint;
    begin
    if a<b then min:=a else min:=b
    end;
    procedure addedge(s,t,c,u,k:longint);
    begin
       inc(l);
       en[l]:=en[s];
       en[s]:=l;
       et[l]:=t;
       ec[l]:=c;
       eu[l]:=u;
       ep[l]:=l+k;
    end;
    procedure build(s,t,u,c:longint);
    begin
       addedge(s,t,c,u,1);
       addedge(t,s,-c,0,-1);
    end;
    function aug(no,m:longint):longint;
    var
    i,d:longint;
    begin
       if no=n then
         begin
         inc(cost,m*dis[1]);
         exit;
         end;
       v[no]:=true;
       i:=ex[no];
       while i<>0 do
         begin
         if (eu[i]>0)and not v[et[i]] and(dis[et[i]]+ec[i]=dis[no]) then
           begin
           d:=aug(et[i],min(m,eu[i]));
           if d>0 then
              begin
              dec(eu[i],d);
              inc(eu[ep[i]],d);
              ex[no]:=i;
              exit(d);
              end;
           end;
         i:=en[i];
         end;
       ex[no]:=i;
       exit(0);
    end;
    function modlabel:boolean;
    var
    d,i,j:longint;
    begin
       d:=maxlongint;
       for i:=1 to n do
         if v[i] then
           begin
           j:=en[i];
           while j<>0 do
              begin
              if (eu[j]>0)and not v[et[j]] and(ec[j]-dis[i]+dis[et[j]]<d) then
                 d:=ec[j]-dis[i]+dis[et[j]];
              j:=en[j]
              end;
           end;
       if d=maxlongint then exit(true);
       for i:=1 to n do
         if v[i] then
           begin
           v[i]:=false;
           inc(dis[i],d);
           end;
       exit(false);
    end;
    function work:longint;
    var i:longint;
    begin
    cost:=0;
    repeat
       for i:=1 to n do ex[i]:=en[i];
       while aug(1,maxlongint)>0 do
         fillchar(v,sizeof(v),0);
    until modlabel;
    work:=cost;
    end;
    function solve(x,d:longint):longint;
    var i,k,t,p,last,cost,lk:longint;
    begin
    fillchar(en,sizeof(en),0);
    fillchar(dis,sizeof(dis),0);
    k:=0; n:=2; t:=x; p:=0;
    while x<>0 do
       begin
       k:=k+x mod 10;
       x:=x div 10;
       inc(p);
       end;
    n:=1; x:=t; l:=k+p+1; last:=1; cost:=1; lk:=0;
    while x<>0 do
       begin
       k:=x mod 10;
       for i:=1 to k do
         begin
         inc(n);
         build(last,n,1,-cost);
         build(n,last+k+1,1,0);
         end;
       cost:=cost*10;
       inc(n);
       if last<>1 then
         begin
         if lk<k then
           build(1,last,k-lk,0);
         if k<lk then
           build(last,n,lk-k,0);
         end;
       last:=n; x:=x div 10;
       if lk<k then lk:=k;
       end;
    build(1,n,1,d);
    solve:=-work;
    end;
    begin
    readln(a,b);
    left:=1; right:=1000000000;
    while right-left>15000 do
       begin
       ans:=(left+right)shr 1;
       if solve(ans,b)>a then
         right:=ans
       else left:=ans;
       end;
    for i:=left to right do
       if solve(i,b)=a then
         begin
         writeln(i);
         halt;
         end;
    end.

  • 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

信息

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