61.187.179.132:8080/JudgeOnline/showproblem
数据那么大暴搜只能去死。。
我想先贪心的跳一会,当距离比较近的时候再暴搜。
我一开始想的贪心是直接按距离。。结果WA。。
然后我编数据找原因。。发现对于那些正方形两个对角点比如0 0 100 100的数据错的很厉害。。
然后我感觉似乎是因为这样贪心的话一开始就会往边上跳。。不顾后来的情况。
所以我又加了个指标就是如果距离一样,那么横纵距离差小的更有优先权。就A掉了。
Code:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<string>
#include<vector>
#include<cstring>
#include<queue>
#define rep(i,n) for(int i=0;i<n;i++)
#define pb push_back
using namespace std;
typedef pair<int,int> pi;
const pi D[]={pi(2,1),pi(1,2),pi(-1,2),pi(-2,1),pi(-2,-1),pi(-1,-2),pi(1,-2),pi(2,-1)};
const int inf=~0U>>1;
inline int abs(int x){return x<0?-x:x;}
inline pi dist(pi a,pi b)
{
int x=abs(a.first-b.first),y=abs(a.second-b.second);
return pi(x+y,abs(x-y));
}
pi operator+(const pi&a,const pi&b)
{
return pi(a.first+b.first,a.second+b.second);
}
ostream& operator<<(ostream& out,const pi&a)
{
out<<"("<<a.first<<","<<a.second<<")";
}
int main()
{
//freopen("in","r",stdin);
pi a,b;int ans=0;
cin>>a.first>>a.second>>b.first>>b.second;
while (dist(a,b).first>10)
{
pi next,Min(inf,inf);
rep(i,8)
{
pi c=a+D[i];pi ncost=dist(c,b);
if(ncost<Min)
Min=ncost,next=c;
}
a=next,ans++;
}
int x=min(a.first,b.first),y=min(a.second,b.second);
pi c=pi(-x,-y);
a=a+c+pi(5,5);b=b+c+pi(5,5);
bool vis[100][100]={0};
int d[100][100];
vis[a.first][a.second]=true;
d[a.first][a.second]=0;
queue<pi> Q;Q.push(a);
while (Q.size())
{
pi t=Q.front();Q.pop();int cost=d[t.first][t.second];
if(t==b) break;
rep(i,8)
{
pi c=t+D[i];
if(c.first>=0&&c.first<100&&c.second>=0&&c.second<100)
if(!vis[c.first][c.second])
{
vis[c.first][c.second]=true;
d[c.first][c.second]=cost+1;
Q.push(c);
}
}
}
cout<<ans+d[b.first][b.second];
}
[HNOI2006]超级英雄Hero
61.187.179.132:8080/JudgeOnline/showproblem
太TMD恶心了。。一眼就看出是匹配。。关键是这个答题是要连续的!
也就是说从1到开始找增广轨找不到就不能再找了。。结果WA了3次
Code:
#include<iostream>
#define rep(i,n) for(int i=0;i<n;i++)
using namespace std;
const int V=1200;
int E[V][2],Link[V],n,m;
bool vis[V];
bool dfs(int x)
{
if(vis[x]) return 0;
vis[x]=1;
for(int i=0,t;i<2;i++)
{
t=E[x][i];
if(Link[t]==-1||dfs(Link[t]))
return Link[t]=x,1;
}
return 0;
}
int main()
{
cin>>n>>m;
rep(i,m) cin>>E[i][0]>>E[i][1];
rep(i,n) Link[i]=-1;
int ans;
for(ans=0;ans<m;ans++){memset(vis,0,sizeof(vis)); if(!dfs(ans)) break;}
cout<<ans<<endl;
}
【VIJOS 1549】 中位数
www.vijos.cn/Problem_Show.asp
也是[CQOI2009]中位数图
额。。设b所在位置为x,
设一个数列S中大于b的数的数量-小于b的数的数量F(S)
那么这个序列由x左边的一些和右边的一些构成,且F(Left)+F(Right)=0。。
那么就很简单了。。从x往右扫描一遍,记录每个F(S)出现了几次,放在Count数组里
再往左扫描一遍,若当前F值为now,只要把答案+上Count[-now]就可以了
0ms1A。。真是爽啊。。
Code:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<string>
#include<vector>
#include<cstring>
#define rep(i,n) for(int i=0;i<n;i++)
#define pb push_back
using namespace std;
const int inf=~0U>>1;
const int maxn=1e5+10;
int main()
{
//freopen("in","r",stdin);
int n,b;int A[maxn];
int C[maxn*2]={0};
cin>>n>>b;int x;
rep(i,n) scanf("%d",A+i),x=(A[i]==b?i:x);
int now=0;
C[now+maxn]++;
for(int i=x+1;i<n;i++)
{
if(A[i]>b) now++;
else now–;
C[now+maxn]++;
}
long long ans=0;
now=0;ans+=C[now+maxn];
for(int i=x-1;i>=0;–i)
{
if(A[i]>b) now++;
else now–;
ans+=C[maxn-now];
}
cout<<ans<<endl;
}
P.S最近在做以前浙江省数学竞赛的卷子,突然灵机一动想出了一道编程题,就交到Vijos上面去了。。不知道能不能通过囧。。
SGU 478. Excursion
acm.sgu.ru/problem.php
我更明白了一个事实,就是我是一个沙茶囧。。
这种题目我在当时比赛的时候居然用带上下界的最大流去做。结果悲剧死。。
实际上简单的贪心就可以了。。如果人变多了让boy回来否则让girl出去。。
Code:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<string>
#include<vector>
#include<utility>
#define rep(i,n) for(int i=0;i<n;i++)
using namespace std;
typedef pair<int,int> pi;
const int inf=~0U>>1;
int main()
{
freopen("in","r",stdin);
int b,g,n;
cin>>b>>g>>n;
vector<pi> A;
int now=g;
rep(i,n)
{
int x;cin>>x;
if(x>=now)
{
b-=x-now;
if(b<0) break;
A.push_back(pi(x-now,0));
now=x;
}
else
{
g-=now-x;
if(g<0) break;
A.push_back(pi(0,now-x));
now=x;
}
}
if(A.size()<n)
cout<<"ERROR"<<endl;
else
{
rep(i,n)
cout<<A[i].first<<" "<<A[i].second<<endl;
}
}
【VIJOS 1629】 8
www.vijos.cn/Problem_Show.asp
啥也别说了。。直接上容斥原理。。
Code:
#include<iostream>
#define rep(i,n) for(int i=0;i<n;i++)
using namespace std;
const int inf=~0U>>1;
typedef long long ll;
int a,b,A[20],n;
int Count(int a,int b,int x)
{
return b/x-(a-1)/x;
}
ll gcd(ll a,ll b)
{
return b?gcd(b,a%b):a;
}
ll lcm(ll a,ll b)
{
return a/gcd(a,b)*b;
}
ll ans=0;int d;
void dfs(int p,ll s,int ch)
{
if(s>b) return;
if(p==n)
{
int d=Count(a,b,s);
if(ch&1) ans-=d;
else ans+=d;
return;
}
ll NewOne=lcm(s,A[p]);
dfs(p+1,NewOne,ch+1);
dfs(p+1,s,ch);
}
void init()
{
cin>>n;
rep(i,n) cin>>A[i];
cin>>a>>b;
}
int main()
{
//freopen("in","r",stdin);
init();
dfs(0,8,0);
cout<<ans<<endl;
}
[VIJOS 1701] Local Maxima
额。。最为VIJOS回归之后做的第一题。还是蛮有意思的。。
传送门
首先可以看出答案是1到n的倒数和。。
有两个办法。。一个是我开始想到的就是设F(x)为1到x的排列的答案。
那么若这个排列第一个是1。那么就是F(x-1)+1否则在中间的1可以忽略掉,就是F(x-1)。。
那么F(x)=( F(x-1)+1 )/x +F(x-1)*(x-1)/x。。
就是F(x)=F(x-1)+1/x。。。
这个方法只有我这样菜的人才想的出来囧。。
一般来说第i个数为Local Maxima的概率就是他为前i个中最大的概率,就是1/i。。
然后+起来。。
不过数据范围太TMD大了。。
我一开始想是不是要用矩阵加速,感觉不是齐次的搞不出来。。。
最后wiki了一下调和数列,发现原来是有公式的。。
zh.wikipedia.org/wiki/%E6%AC%A7%E6%8B%89-%E9%A9%AC%E6%AD%87%E7%BD%97%E5%B0%BC%E5%B8%B8%E6%95%B0
因为精度的问题,对于n<=10^6次方的时候。。暴力计算,
否则使用公式。
Code:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<string>
#include<vector>
#include<cmath>
#define rep(i,n) for(int i=0;i<n;i++)
using namespace std;
const int inf=~0U>>1;
const int limit=1e6;
int main()
{
int n;cin>>n;double ans=0;
if(n<=limit)
for(double i=1;i<=n;i++)
ans+=1/i;
else
ans=log((double)n)+0.57721566490153286060651209;
printf("%0.8lfn",ans);
}P.S我的vijos号由于注册的比较早。不叫WJMZBMR。。好像是453844077囧。。我在想是不是为了统一风格就不要原来的号了又舍不得100多道题目囧。。
看Saw有感
寒假的作业,由于上个学期一直搞OI随笔一篇都没写,作文差了N篇,才补好一篇囧。
这个实际上很早就写了。。但当时太激动,我怕老师觉得我是BT所以改了改囧。
看Saw有感
someone lives without thanksgiving,
but not you ,any more .
Saw的中文名就是电锯惊魂,说白了就是一部血腥+恐怖片,但我看了之后却觉得,这部片子的导演很伟大,这的的确确是一部反映当前时代精神的片子。
血腥、暴力?嗯,可这在失去灵魂的人面前又算什么?Saw的海报都是一个个失去灵魂的人戴着刑具,脸上除了痛苦什么都没有。实际上这个时代的人的神经已经彻底麻木了,Saw的主角约翰明白还有一种办法可以拯救人,就是痛苦。信仰,宗教,都是虚的,尽管曾经是对的,但是在现在的时代精神面前早已土崩瓦解了,每个人都不再能从他人的脸上看到上帝(哎,我以前是多么相信这个。。),自我的存在意识都逐渐模糊了,人发明了那么多机器,到头来反而被成为机器的机器。
痛苦?看到他人的痛苦,也感觉到痛苦,内心才能不再麻木?感觉到痛苦,才能感觉到自己原来是存在的?原来不仅仅是视觉+听觉+触觉?不是在看三维电影?还是这个世界中的?
活了几十年的人反而要让别人教他体验到自己的存在,很可笑?很可悲?一点也不,这就是事实。
Saw里面约翰得了绝症,快死了,他去自杀,没成功,于是决定将余生用来救赎他人的灵魂。折磨他人,让他人对生命感恩。第一部结束的时候,导演还是忍不住插播了画外音,someone lives without thanksgiving, but not you any more..也许是说给经过考验的医生说的,也许是说给观众听的。
我开始明白为什么有那么多人喜欢自残,那么多人执着于血腥片了,跟爱情和死亡一个道理,想感受到自己存在。
you’re wrong.
No one will change
但这真的是拯救么,第一部中被约翰救赎的阿凡达在第三部中说you’re wrong , No one will change,也许这本来就是骗人的,约翰只是在报复,报复他没有生命了。约翰之所以是对的是因为他头上有上帝的时钟,一个即将死亡的人?一种宿命感?对他人生命的妒忌?我也不知道是什么。也许就是这样。
TopCoder HigSchool 2010 Round 1
这是第一次比赛。。本来是海选出500个人的。。结果总共都没有500个人囧。。
由于明天就要上学了。。本来不想参加的。。但是根本没有睡意。。于是就上了。。
第一题这个太水了。。怎么做都可以。。
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
using namespace std;
class TheSequencesLevelOne
{
public:
vector <int> find(vector <int>);
};
vector <int> TheSequencesLevelOne::find(vector <int> s)
{
vector<int> ans;
for(int i=0; i<s.size(); i++)
{
int a;
for(int t=0; t<=7; t++)
{
int x=s[i];
x-=t;
if(x%4==0||x%7==0)
{
a=x;
break;
}
x+=2*t;
if(x%4==0||x%7==0)
{
a=x;
break;
}
}
ans.push_back(a);
}
return ans;
}
//Powered by [KawigiEdit] 2.0!
第二题找规律啊。。奇数位放当前最小的,放了后删掉,偶数位放当前第二小的,放了后删掉,
最后一位特判一下就可以了。。
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
using namespace std;
class TheSequencesLevelTwo
{
public:
vector <int> find(vector <int>);
};
vector <int> TheSequencesLevelTwo::find(vector <int> s)
{
set<int> S(s.begin(),s.end());
vector<int> Ans;
for(int i=0; i<s.size()-1; i++)
{
if(i%2==0)
{
Ans.push_back(*S.begin());
S.erase(S.begin());
}
else
{
Ans.push_back(*(++S.begin()));
S.erase(++S.begin());
}
}
Ans.push_back(*S.begin());
return Ans;
}
//Powered by [KawigiEdit] 2.0!
第三题的题目可以转化成分成有序的两堆不包括最大数,两堆中相邻元素差不超过K。那么从小到大一个个考虑元素,每个堆有意义的只有大小和最上面的数。。同时一定有一个堆最上面是当前最大的数,所以只要记录3个值就可以了。。然后递推。。算出所有的结果。。然后判断一下最大数就可以了。。
我也不知道为什么我非常WS的用了动态申请。。
dp[i][j][k]当前左边堆有i个,右边堆有j最大的那个在左边堆的最上面,k是右边堆最上面数的编号
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
using namespace std;
class TheSequencesLevelThree
{
public:
int find(vector <int>, int);
};
const int mod=1234567891;
int TheSequencesLevelThree::find(vector <int> s, int K)
{
sort(s.begin(),s.end());
long long***dp;
int n=s.size();
if(n<3) return 0;
dp=new long long**[n+1];
for(int i=0; i<=n; i++)
{
dp[i]=new long long*[n+1];
for(int j=0; j<=n; j++)
{
dp[i][j]=new long long[n+1];
for(int k=0; k<=n; k++)
dp[i][j][k]=0;
}
}
dp[0][0][0]=1;
int t;
for(int l=0; l<n; l++)
for(int i=0; i<=l; i++)
{
int j=l-i;
for(int k=0; k<n; k++)
if(t=dp[i][j][k])
{
int now=i+j;
if(i==0||s[now]-s[now-1]<=K)
dp[i+1][j][k]+=t,dp[i+1][j][k]%=mod;
if(j==0||s[now]-s[k]<=K)
dp[j+1][i][now-1]+=t,dp[j+1][i][now-1]%=mod;
}
}
long long ans=0;
for(int l=1; l<n-1; l++)
{
int r=n-l-1;
for(int k=0; k<n; k++)
{
int x=dp[l][r][k];
if(s[n-1]-s[k]<=K&&s[n-1]-s[n-2]<=K)
ans+=x,ans%=mod;
}
}
ans*=2;
ans%=mod;
return ans;
}
//Powered by [KawigiEdit] 2.0!
我还Cha掉了一个人的程序。。算法不知道对不对。一看他的特判就知道他判错了。。处女Cha啊。。
我的Coding的速度真是慢死了。。分低的要命。。囧
PS.那个人算法真是对的。。
这么大的随机数据都过了。。反而被我这个Cha掉囧。。
发现一个语法高亮的网站非常NB
我找了N多地方都没有发现什么网站可以高亮scala的。。
后来我看到了一篇文章。找到了这个网站:
www.andre-simon.de/doku/highlight/en/highlight_demo.html
自己看啦,太NB了。。基本可以高清任何代码。。发个效果图
C++:
#include <stdio.h>
int main(void)
{
char msg[13] =
{ 0110, 0145, 0154, 0154, 0157, 054, 040,
0127, 0157, 0162, 0154, 0144, 012 };
int i;
for ( i=0; i<13; i++ )
putchar(msg[i]);
return 0;
}
Java:
public class Fibonacci {
public static long fib(int n) {
if (n <= 1) return n;
else return fib(n-1) + fib(n-2);
}
public static void main(String[] args) {
int N = Integer.parseInt(args[0]);
for (int i = 1; i <= N; i++)
System.out.println(i + ": " + fib(i));
}
}
[HNOI2008]越狱
倒。。这么水的题目都有的。。
Link:61.187.179.132:8080/JudgeOnline/showproblem
正着想有点麻烦。。倒过来想。。
一共有m^n种情况,其中不能越狱的情况中,如果从左往右考虑的话,第一个是m种,其余都是m-1种
所以就是(m-1)^(n-1)*m。。用一个二分计算乘方就可以了。。
减一下就可以了囧。。
Code:
#include<iostream>
using namespace std;
typedef long long ll;
const int mod=100003;
ll m,n;
inline void mul(ll&a,int b){a*=b;a%=mod;}
int power(ll x,int base)
{
if(x==0) return 1;
ll tmp=power(x/2,base);
mul(tmp,tmp);
if(x&1) mul(tmp,base);
return tmp;
}
int main()
{
cin>>m>>n;
int all=power(n,m);
ll sub=power(n-1,m-1);
mul(sub,m);
int ans=all-sub;if(ans<0) ans+=mod;
cout<<ans<<endl;
}
本高亮代码使用codeHl生成,