SGU 175

这个题目实际上只要递归的搞下去就可以了。。
脑子一定要清楚。。否则要悲剧的。。
import java.util.*;
import java.math.*;
public class Solution
{
static Scanner in=new Scanner(System.in);
BigInteger value(int x){return BigInteger.valueOf(x);}
static void print(Object x){System.out.println(x);}
static int Code(int n,int q)
{
if(n==1) return 1;
int k=n/2;
if(q<=k) return Code(k,k-q+1)+n-k;
return Code(n-k,n-k-(q-k)+1);
}
public static void main(String args[])
{
int n=in.nextInt();
int q=in.nextInt();
print(Code(n,q));
}
}

SGU 111

就是给你一个1000位以下的数。。求他的平方根(round down)。。
我由于是java的。。但是java中biginteger没有sqrt的功能。。我只好用二分查找了。。
如果位数是n的话。。二分是n的。。乘法是nlogn的。。所以总共就是n^2logn的。
其实是有10n的好办法的。。
不过我太懒了。。
Code:
import java.util.*;
import java.math.*;
public class Main
{
static Scanner in=new Scanner(System.in);
public static void main(String args[])
{
BigInteger l,r,m,x,tmp;
l=BigInteger.valueOf(0);x=in.nextBigInteger();
r=x.abs().add(BigInteger.ONE);
while(l.add(BigInteger.ONE).compareTo(r)==-1)
{
m=l.add(r).divide(BigInteger.valueOf(2));
if(m.multiply(m).compareTo(x)!=1)
l=m;
else
r=m;
}
System.out.println(l);
}
}

Ural 1009,1012,1013 K-based numbers,Version 1-3

暴冷。。直接DP 一个程序A3题。。
Java的高精度实在太无敌了。。
import java.util.*;
import java.math.*;
public class Main
{
static Scanner in=new Scanner(System.in);
public static void main(String args[])
{
int n,k;
BigInteger notZero,zero;
n=in.nextInt();k=in.nextInt();
zero=BigInteger.valueOf(0);notZero=BigInteger.valueOf(k-1);
for(int i=1;i<n;i++)
{
BigInteger nZero,nNotZero;
nZero=notZero;
nNotZero=zero.add(notZero).multiply(BigInteger.valueOf(k-1));
zero=nZero;
notZero=nNotZero;
}
System.out.println(zero.add(notZero));
}
}

Ural 1005

就是说不到20堆石头。分成2大堆。。让他们绝对值最小。。
直接dfs。。第一次用java写这种题。。感觉还不错。。
实际上java跟C++也差不了多少啊。。
还有就是我用java在pku上虐了七八道高精度的题目。。真是爽!

import java.util.*;
class solve
{
static Scanner in=new Scanner(System.in);
int[] W;
int n,allSum,ans;
void work()
{
init();
dfs(0,0);
System.out.println(ans);
}
void init()
{
n=in.nextInt();
W=new int[n];
allSum=0;
for(int i=0;i<n;i++)
{
W[i]=in.nextInt();
allSum+=W[i];
}
ans=allSum;
}
void checkans(int newAns)
{
newAns=newAns<0?-newAns:newAns;
if(newAns<ans) ans=newAns;
}
void dfs(int pos,int sum)
{
if(pos==n) {checkans(allSum-2*sum);return;}
dfs(pos+1,sum+W[pos]);
dfs(pos+1,sum);
}
}
public class Main
{
public static void main(String[] args)
{
solve now=new solve();
now.work();
}
}

SGU 247

知道我为什么这么快么。。因为我。。使用了ST大法!
Java的计算程序。。java里面有biginteger类。。可以用来高精。。
import java.util.*;
import java.math.BigInteger;
import java.io.*;
public class Solution
{
static Scanner in=new Scanner(System.in);
static String solve(Integer p)
{
BigInteger ans=BigInteger.ONE;
for(Integer i=p+1;i<=2*p;i++)
ans=ans.multiply(BigInteger.valueOf(i));
for(Integer i=2;i<=p;i++)
ans=ans.divide(BigInteger.valueOf(i));
ans=ans.divide(BigInteger.valueOf(p));
ans=ans.add(BigInteger.valueOf(2));
return ans.toString();
}
public static void main(String[] args)
throws IOException
{
PrintWriter out=new PrintWriter("out");
int n=in.nextInt();out.println("{0,");
for(int i=1;i<n;i++) out.println("""+solve(i)+"",");
out.println("0,}");
out.close();
}
}因为以前我写过一个c++的打表机。。所以我就用c++交表了。。

SRM 454 DIV 1 Level 2

就是说用火柴来表示数。。给你一个18位以下的10进制数。。
最多移动K根火柴。。求出能形成多少不同的数。。
dp啊。。
F[i][plus][minus]表示前i个中,移进plus根火柴,移开minus根火柴,有几种不同的数。。
然后预处理或者直接手打出火柴两两之间的移动关系( 有人就是手打的)。。
就可以方便的DP了。。
关键就是这个状态是3维的。。一开始我一直以为是2维的。。想了半天也没结果。。
答案就是Sum{F[n][i][i]|0<=i<=K}。。
感觉就是这道题如果从记忆化搜索的角度来想比较方便。。现在我发现记忆化搜索在很多时候比子问题重叠的思考方法要重要多了。。

TopCoder SRM 4XX DIV 2 Level 3

忘了是SRM几了。。不过是道好题啊。。
已知三个整数x,y,z。。给出它们的上下界。。求出x*y=z的三元组有几个。。
由于上下界是10^10次方的。。暴力枚举x和y的话是10^20。。只能去死。。
如果枚举z。。然后可以根据y的上下界得出满足条件的x的上下界。。再与真实的x上下界求交。。
是10^10。。还是太慢了。。。
想了N久。。最后灵机一动。。
核心就是要降低枚举的复杂度。。注意到下界可以通过减法原理消掉。。那么只需要考虑上界。。
问题就变成了:
 x,y,z>=1
x<=maxx
y<=maxy
x*y=z<=maxz
关键就是如果x*y<=maxz的话,那么x和y必然有一个小于根号z。。
首先枚举x小于根号z的情况,然后枚举y小于根号z求x大于跟号z的情况(防止重复)。10^5。。问题就解决了。。
忘了是SRM几了。。找不到代码了。。

悲剧了。。

这次USACO的月赛比的很悲剧。。第一题代码搞错了一行结果全WA。。
第二题少了几个判断结果N个点seg error了。。
第3个最简单的我全WA光。。结果发现是线段树写错了。。
啊啊啊。。BS我自己啊。。太ZB了。。

为什么会悲剧呢?题目我都会做啊,感觉跟NOIP的时候是一个道理,知道怎么做跟打出来让它做完全是两码事,脑子里面有算法一点用都没有,码不出来照样悲剧,就像NOIP的时候我全悲剧在那个强连通上了。。根本没写过几遍偏偏要去写。。绝对是ZB的表现。。这就是一个教训就是不熟的代码千万别打。。哪怕损点分也无所谓。。NOIP的时候如果不打强连通还可以DP出50分。。然后就有大把的时间去A第4题。。说不定就喜剧了。。总之也是一个抉择啦。。如果对自己不是非常有自信。。还是先做有把握的题目吧。。。像这次我第二题写的快疯掉。。我估计就肯定对不了。。果然悲剧的要死。。还不如把第一题再调试调试。。然后第三题也可以检查出错误。。然后就又喜剧了。。

总而言之言而总之呢。。我得记住永远不要相信自己能A完所有的题而太苛求一道题。。人要清醒。。能拿多少是多少。。