1323 条题解
-
0frankchenfu LV 8 @ 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;
}
祝大家刷题快乐,从这里开始。 -
02016-12-11 18:55:20@
以下题解不必去理解,为搜集到的大牛解法,当然,也有自己写的
-
02016-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 ] -
02016-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. -
02016-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;) -
02016-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);
} -
02016-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;
} -
02016-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));
} -
02016-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;
} -
02016-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;
} -
02016-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;
} -
02016-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;
} -
02016-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的距离和并输出
} -
02016-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);
} -
02016-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;
} -
02016-12-11 18:45:02@
通过100纪念
-
02016-12-04 15:03:40@
#include <iostream>
using namespace std;
int main()
{
int a, b;
cin >> a >> b;
cout << a + b << endl;
return 0;
} -
02016-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. -
02016-10-01 20:19:51@
Python题解
import sys
a , b= map(int,sys.stdin.readline().split())
print a + b -
02016-09-21 22:14:00@
信息
- ID
- 1000
- 难度
- 9
- 分类
- (无)
- 标签
- (无)
- 递交数
- 74446
- 已通过
- 28492
- 通过率
- 38%
- 被复制
- 223