# Problem A Calculus Midterm

Accept: 0    Submit: 0
Time Limit: 1000 mSec    Memory Limit : 32768 KB

## Problem Description

Yellowstar刚考完微积分期中考，微积分期中考卷一共三个部分，8道选择题每题3分，8道填空题，每题2分，10题答题每题6分，总分100分。Yellowstar考完期中考后已经失去了计算能力，他只记得每部分对的题数，现在想请你帮忙计算一下他的得分，能否通过考试。

8 8 10
0 0 0

## Sample Output

I passed the exam.
100
Exam was too hard.
0

## Source Code

/*Sherlock and Watson and Adler*/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<queue>
#include<stack>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<cmath>
#include<complex>
#include<string>
#include<algorithm>
#include<iostream>
#define exp 1e-10
using namespace std;
const int N = 100005;
const int M = 40;
const int inf = 100000000;
const int mod = 2009;
int main()
{
int x,y,z,sum;
while(~scanf("%d%d%d",&x,&y,&z))
{
sum=x*3+y*2+z*6;
if(sum>=60)
puts("I passed the exam.");
else
puts("Exam was too hard.");
printf("%d\n",sum);
}
return 0;
}

# Problem B 翻翻棋

Accept: 0    Submit: 0
Time Limit: 1000 mSec    Memory Limit : 32768 KB

’#’表示空格

’*’表示红方帅

’.’表示黑方将

1
######.#
#####*##
########
########

Black win

## Source Code

/*Sherlock and Watson and Adler*/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<queue>
#include<stack>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<cmath>
#include<complex>
#include<string>
#include<algorithm>
#include<iostream>
#define exp 1e-10
using namespace std;
const int N = 100005;
const int M = 40;
const int inf = 100000000;
const int mod = 2009;
char s[4][15];
int main()
{
int t,i,j,x1,y1,x2,y2,d;
scanf("%d",&t);
while(t--)
{
for(i=0;i<4;i++)
scanf("%s",s[i]);
for(i=0;i<4;i++)
for(j=0;j<8;j++)
if(s[i][j]=='*')
x1=i,y1=j;
else if(s[i][j]=='.')
x2=i,y2=j;
d=abs(x2-x1)+abs(y2-y1);
if(d%2)
puts("Red win");
else
puts("Black win");
}
return 0;
}

# Problem C 平行四边形数

Accept: 0    Submit: 0
Time Limit: 2000 mSec    Memory Limit : 32768 KB

4
0 1
1 0
1 1
2 0

1

## Source Code

/*Sherlock and Watson and Adler*/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<queue>
#include<stack>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<cmath>
#include<complex>
#include<string>
#include<algorithm>
#include<iostream>
#define exp 1e-10
using namespace std;
const int N = 505;
const int M = 40;
const int inf = 100000000;
const int mod = 2009;
struct node
{
int x,y;
}s[N],d[N*N];
bool cmp(node x,node y)
{
if(x.x!=y.x)
return x.x<y.x;
return x.y<y.y;
}
int main()
{
int n,i,j,p,c;
while(~scanf("%d",&n))
{
p=c=0;
for(i=0;i<n;i++)
scanf("%d%d",&s[i].x,&s[i].y);
for(i=0;i<n;i++)
for(j=i+1;j<n;j++)
{
d[p].x=s[i].x+s[j].x;
d[p].y=s[i].y+s[j].y;
p++;
}
sort(d,d+p,cmp);
for(i=0,j=1;i<p&&j<p;i=j,j++)
{
while(d[j].x==d[i].x&&d[j].y==d[i].y)
j++;
c+=(j-i-1)*(j-i)/2;
}
printf("%d\n",c);
}
return 0;
}

# Problem D 炉石传说

Accept: 0    Submit: 0
Time Limit: 1000 mSec    Memory Limit : 32768 KB

## Problem Description

GG学长虽然并不打炉石传说，但是由于题面需要他便学会了打炉石传说。但是传统的炉石传说对于刚入门的GG学长来说有点复杂，所以他决定自己开发一个简化版的炉石传说。

2
3
4 4 5 5 6 6
1 1 2 2 3 3
3
4 4 5 5 6 6
1 4 2 4 3 4

Yes
No

## Source Code

/*Sherlock and Watson and Adler*/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<queue>
#include<stack>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<cmath>
#include<string>
#include<algorithm>
#include<iostream>
#define exp 1e-10
using namespace std;
const int N = 505;
const int M = 1005;
const int inf = 1000000007;
const int mod = 2009;
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int Map[N][N];//存图
int pre[N];//记录当前点的前驱
int level[N];//记录距离标号
int gap[N];//gap常数优化
int NV,NE;
//入口参数vs源点，vt汇点
int SAP(int vs,int vt,int n)
{
memset(pre,-1,sizeof(pre));
memset(level,0,sizeof(level));
memset(gap,0,sizeof(gap));
gap[0]=n;
int v,u=pre[vs]=vs,maxflow=0,aug=inf;
while(level[vs]<n)
{
//寻找可行弧
for(v=1;v<=n;v++)
if(Map[u][v]>0&&level[u]==level[v]+1)
break;
if(v<=n)
{
pre[v]=u;
u=v;
if(v==vt)
{
aug=inf;
//寻找当前找到的一条路径上的最大流
for(int i=v;i!=vs;i=pre[i])
if(aug>Map[pre[i]][i])
aug=Map[pre[i]][i];
maxflow+=aug;
//更新残留网络
for(int i=v;i!=vs;i=pre[i])
{
Map[pre[i]][i]-=aug;
Map[i][pre[i]]+=aug;
}
u=vs;//从源点开始继续搜
}
}
else
{
//找不到可行弧
int minlevel=n;
//寻找与当前点相连接的点中最小的距离标号
for(v=1;v<=n;v++)
if(Map[u][v]>0&&minlevel>level[v])
minlevel=level[v];
gap[level[u]]--;//(更新gap数组）当前标号的数目减1；
if(gap[level[u]]==0)
break;//出现断层
level[u]=minlevel+1;
gap[level[u]]++;
u=pre[u];
}
}
return maxflow;
}
int a[N],b[N],c[N],d[N];
int main()
{
int n,m,u,v,cap;
int t,i,j;
scanf("%d",&t);
while(t--)
{
memset(Map,0,sizeof(Map));
scanf("%d",&n);
for(i=1;i<=n;i++)
scanf("%d%d",&a[i],&b[i]);
for(i=1;i<=n;i++)
scanf("%d%d",&c[i],&d[i]);
for(i=1;i<=n;i++)
{
Map[1][i+1]=1;
for(j=1;j<=n;j++)
{
if(a[i]>d[j]&&b[i]>=c[j])
Map[i+1][j+n+1]=1;
Map[j+n+1][2*n+2]=1;
}
}
if(SAP(1,n*2+2,n*2+2)==n)
puts("Yes");
else
puts("No");
}

return 0;
}  

# Problem E ~APTX4869

Accept: 0    Submit: 0
Time Limit: 1000 mSec    Memory Limit : 32768 KB

## Problem Description

1.解药由n种原料构成；

2.对于两种不同的的原料a,b，它们之间有个影响值f(a,b)；

3.需要把原料分成两个部分X,Y，每部分中至少有一种原料；

4.解药的效果由分别属于X,Y的原料之间，最小的影响值决定，即

## Input

2<=n<=800。当i!=j时，0<=f(i,j)<=1000000；当i=j时，f(i,j)=-1。

3
-1 100 300
100 -1 200
300 200 -1

200

## Source Code

/*Sherlock and Watson and Adler*/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<queue>
#include<stack>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<cmath>
#include<complex>
#include<string>
#include<algorithm>
#include<iostream>
#define exp 1e-10
using namespace std;
const int N = 805;
const int M = 40;
const int inf = 100000000;
const int mod = 2009;
int n,s[N][N],c[N],b[N*N/2],p;
bool v[N];
int fun(int x)
{
if(c[x]!=x)
c[x]=fun(c[x]);
return c[x];
}
void init()
{
for(int i=1;i<=n;i++)
c[i]=i;
memset(v,false,sizeof(v));
}
bool judge(int x)
{
int i,j,k,t=0;
init();
for(i=1;i<=n;i++)
for(j=i+1;j<=n;j++)
if(s[i][j]<x)
c[fun(i)]=fun(j);
for(i=1;i<=n;i++)
{
k=fun(i);
if(!v[k])
{
t++;
v[k]=true;
}
}
if(t>1)
return true;
return false;
}
void Binary()//二分答案
{
int l=0,r=p-1,ans=0;
while(l<r)
{
int mid=(l+r)>>1;
if(judge(b[mid]))
{
l=mid+1;
ans=max(ans,b[mid]);
}
else
r=mid;
}
if(l==r&&judge(b[l]))
ans=max(ans,b[l]);
printf("%d\n",ans);
}
int main()
{
int i,j;
while(~scanf("%d",&n))
{
p=0;
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
{
scanf("%d",&s[i][j]);
if(j>i)
b[p++]=s[i][j];
}
sort(b,b+p);
p=unique(b,b+p)-b;
Binary();
}
return 0;
}
/*
3
-1 100 300
100 -1 200
300 200 -1
4
-1 200 200 100
200 -1 200 100
200 200 -1 200
100 100 200 -1
4
-1 200 100 100
200 -1 200 100
100 200 -1 200
100 100 200 -1
*/

# Problem F 牧场物语

Accept: 0    Submit: 0
Time Limit: 1000 mSec    Memory Limit : 32768 KB

2
11 14
16 12

53

## Problem Idea

ans[k][(x1,y1)][(x2,y2)]=max{

ans[k-1][(x1-1,y1)][(x2-1,y2)],

ans[k-1][(x1,y1-1)][(x2,y2-1)],

ans[k-1][(x1-1,y1)][(x2,y2-1)],

ans[k-1][(x1,y1-1)][(x2-1,y2)]

}

ans[k][x1][x2]=max{

ans[k-1][x1-1][x2-1],

ans[k-1][x1][x2],

ans[k-1][x1-1][x2],

ans[k-1][x1][x2-1]

}

## Source Code

/*Sherlock and Watson and Adler*/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<queue>
#include<stack>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<cmath>
#include<complex>
#include<string>
#include<algorithm>
#include<iostream>
#define exp 1e-10
using namespace std;
const int N = 105;
const int M = 40;
const __int64 inf = 1e12;
const int mod = 2009;
int s[N][N];
__int64 ans[2][N][N];
int main()
{
int n,i,j,k,c;
while(~scanf("%d",&n))
{
for(i=0;i<=n;i++)
for(j=0;j<=n;j++)
{
ans[0][i][j]=ans[1][i][j]=-inf;
if(i!=0&&j!=0)
scanf("%d",&s[i][j]);
}
ans[0][1][1]=s[1][1];
for(c=0,k=1;k<2*n-1;k++)
{
c^=1;
for(i=1;i<=min(k+1,n);i++)
for(j=1;j<=min(k+1,n);j++)
{
ans[c][i][j]=max(max(ans[c^1][i][j],ans[c^1][i-1][j-1]),max(ans[c^1][i-1][j],ans[c^1][i][j-1]));
if(i==j)
ans[c][i][j]+=s[i][k+2-i];
else
ans[c][i][j]+=s[i][k+2-i]+s[j][k+2-j];
}
}
printf("%I64d\n",ans[c][n][n]);
}
return 0;
}

# Problem G 国王的出游

Accept: 0    Submit: 0
Time Limit: 1000 mSec    Memory Limit : 32768 KB

## Input

1 <= x0, y0, x1, y1, ri, ai, bi<= 2*10^9,1 <= N <= 10^5

5 7 6 11
3
5 3 8
6 7 11
5 2 5

1 1 2 10
2
1 1 3
2 6 10

4
-1

## Problem Idea

TLE代码(下面有正确代码,往下看)如下:

/*Sherlock and Watson and Adler*/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<queue>
#include<stack>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<cmath>
#include<complex>
#include<string>
#include<algorithm>
#include<iostream>
#define exp 1e-10
using namespace std;
const int N = 100005;
const int M = 40;
const int inf = 100000000;
const int mod = 2009;
struct node
{
int x,y,c;
node(){}
node(int x0,int y0,int c0):x(x0),y(y0),c(c0){}
};
int g[8][2]={{1,0},{1,-1},{0,-1},{-1,-1},{-1,0},{-1,1},{0,1},{1,1}};
map<pair<int,int>,bool> m;
int bfs(int x0,int y0,int x1,int y1)
{
int i;node u;
queue<node> q;
q.push(node(x0,y0,0));
m[make_pair(x0,y0)]=false;
while(!q.empty())
{
u=q.front();
q.pop();
for(i=0;i<8;i++)
{
x0=u.x+g[i][0];
y0=u.y+g[i][1];
if(x0==x1&&y0==y1)
return u.c+1;
if(m[make_pair(x0,y0)])
{
m[make_pair(x0,y0)]=false;
q.push(node(x0,y0,u.c+1));
}
}
}
return -1;
}
int main()
{
int x0,y0,x1,y1,n,i,r,a,b;
while(~scanf("%d%d%d%d",&x0,&y0,&x1,&y1))
{
m.clear();
scanf("%d",&n);
while(n--)
{
scanf("%d%d%d",&r,&a,&b);
for(i=a;i<=b;i++)
m[make_pair(r,i)]=true;
}
if(x0==x1&&y0==y1)
puts("0");
else
printf("%d\n",bfs(x0,y0,x1,y1));
}
return 0;
}

## Source Code

/*Sherlock and Watson and Adler*/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<queue>
#include<stack>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<cmath>
#include<complex>
#include<string>
#include<algorithm>
#include<iostream>
#define exp 1e-10
using namespace std;
const int N = 100005;
const int M = 40;
const int inf = 100000000;
const int mod = 2009;
struct node
{
int x,y,c;
node(){}
node(int x0,int y0,int c0):x(x0),y(y0),c(c0){}
};
int p,g[8][2]={{1,0},{1,-1},{0,-1},{-1,-1},{-1,0},{-1,1},{0,1},{1,1}};
pair<int,int> m[N];
bool v[N];
int bfs(int x0,int y0,int x1,int y1)
{
int i,k;node u;
queue<node> q;
q.push(node(x0,y0,0));
k=lower_bound(m,m+p,make_pair(x0,y0))-m;
if(m[k]==make_pair(x0,y0))
v[k]=false;
while(!q.empty())
{
u=q.front();
q.pop();
for(i=0;i<8;i++)
{
x0=u.x+g[i][0];
y0=u.y+g[i][1];
if(x0==x1&&y0==y1)
return u.c+1;
k=lower_bound(m,m+p,make_pair(x0,y0))-m;
if(m[k]==make_pair(x0,y0)&&v[k])
{
v[k]=false;
q.push(node(x0,y0,u.c+1));
}
}
}
return -1;
}
int main()
{
int x0,y0,x1,y1,n,i,r,a,b;
while(~scanf("%d%d%d%d",&x0,&y0,&x1,&y1))
{
p=0;
memset(v,false,sizeof(v));
scanf("%d",&n);
while(n--)
{
scanf("%d%d%d",&r,&a,&b);
for(i=a;i<=b;i++)
{
m[p]=make_pair(r,i);
v[p++]=true;
}
}
sort(m,m+p);
p=unique(m,m+p)-m;
if(x0==x1&&y0==y1)
puts("0");
else
printf("%d\n",bfs(x0,y0,x1,y1));
}
return 0;
}

# Problem H 第十四个目标

Accept: 0    Submit: 0
Time Limit: 1000 mSec    Memory Limit : 32768 KB

## Problem Description

(如果你看不懂上面在说什么，这题是求一个数列中严格递增子序列的个数。比如数列(1,3,2)的严格递增子序列有(1)、(3)、(2)、(1,3)、(1,2)，共5个。长得一样的但是位置不同的算不同的子序列，比如数列(3,3)的答案是2。)

3
1 3 2

5

## Source Code

/*Sherlock and Watson and Adler*/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<queue>
#include<stack>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<cmath>
#include<complex>
#include<string>
#include<algorithm>
#include<iostream>
#define exp 1e-10
using namespace std;
const int N = 100005;
const int M = 40;
const int inf = 100000000;
const int mod = 1000000007;
int s[N],a[N],n;
__int64 c[N];
int lowbit(int t)
{//计算c[t]展开的项数
return t&(-t);
}
void update(int i,__int64 x)
{
while(i<=n)
{
c[i]=(c[i]+x)%mod;
i+=lowbit(i);
}
}
__int64 Sum(int n) //求前n项的和.
{
__int64 sum=0;
while(n>0)
{
sum=(sum+c[n])%mod;
n-=lowbit(n);
}
return sum;
}
int main()
{
int i,j,k;
__int64 ans;
while(~scanf("%d",&n))
{
memset(c,0,sizeof(c));
ans=0;
for(i=0;i<n;i++)
{
scanf("%d",&s[i]);
a[i]=s[i];
}
sort(a,a+n);
k=unique(a,a+n)-a;
for(i=0;i<n;i++)
s[i]=lower_bound(a,a+k,s[i])-a+1;
/*for(i=0;i<n;i++)
printf("%d ",s[i]);*/
for(i=0;i<n;i++)
update(s[i],Sum(s[i]-1)+1);
/*for(i=1;i<=n;i++)
printf("%I64d ",c[i]);*/
printf("%I64d\n",Sum(n));
}
return 0;
}