两位队友的博客:
http://hzwer.com/
http://kuribohg.github.io/
BEH三题是我写的,其余题目鸣谢二位大腿。
A:Banana
开始样例错了。
代码:
#include
#include
#include
#include
using namespace std;
int T,n,m,a[100][100],b[100][100],ans[100][100];
int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
for(int i=1;i<=50;i++)
for(int j=1;j<=50;j++)
a[i][j]=0,b[i][j]=0,ans[i][j]=0;
for(int i=1,x,y;i<=n;i++)
scanf("%d%d",&x,&y),a[x][y]=1;
for(int i=1,x,y;i<=m;i++)
scanf("%d%d",&x,&y),b[x][y]=1;
for(int i=1;i<=50;i++)
for(int j=1;j<=50;j++)
for(int k=1;k<=50;k++)
if(a[i][k]&&b[k][j]) ans[i][j]=1;
for(int i=1;i<=50;i++)
for(int j=1;j<=50;j++)
if(ans[i][j]) printf("%d %d\n",i,j);
puts("");
}
return 0;
}
B:Out-out control cars
题意:两个三角形匀速直线运动,问是否会撞上。
题解:只需单独计算每个三角形的某个顶点是否会和另一个三角形撞上,进一步地,只需要计算每个三角形的每个顶点是否与另一个三角形的每一条边撞上。方法就是计算一下相对速度(建立一个坐标系,相当于三角形静止,顶点匀速直线运动),然后问题转化为射线和线段相交,解二元一次方程组即可。
代码:
#include
#include
#include
#include
#include
using namespace std;
const double eps=1e-10;
bool solve_mat(double a00,double a01,double a10,double a11,double b0,double b1,double &x0,double &x1){
double det=a00*a11-a01*a10;
if(fabs(det)1) return false;
return true;
}
bool work(void){
Point A[3],Ad;
Point B[3],Bd;
for(int i=0;i<3;i++) scanf("%lf%lf",&A[i].x,&A[i].y);scanf("%lf%lf",&Ad.x,&Ad.y);
for(int i=0;i<3;i++) scanf("%lf%lf",&B[i].x,&B[i].y);scanf("%lf%lf",&Bd.x,&Bd.y);
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
Point p=A[i];
Point d=Ad-Bd;
Point a=B[j],b=B[(j+1)%3];
if(hit(p,d,a,b)) return true;
p=B[i];
d=Bd-Ad;
a=A[j],b=A[(j+1)%3];
if(hit(p,d,a,b)) return true;
}
}
return false;
}
int main(){
int T;scanf("%d",&T);
for(int tot=1;tot<=T;tot++){
printf("Case #%d: ",tot);
if(work()) printf("YES\n");
else printf("NO\n");
}
return 0;
}
C:Coconut
代码:
#include
D:Hack Portals
题意:数轴上有一堆点。你可以每秒走长度1,也可以静止。每个点有一个出现时间,你必须按任意顺序访问所有的点(在其出现之后),你一开始在0,最后回到坐标K,问最少需要多少秒。坐标均为整数,点数和坐标不超过1000,出现时间不超过32768.
题解:枚举一开始在0静止的时长。然后一定是:先走到没被访问的最右点,再走到没被访问的最左点……直到完成。该过程可以O(n)模拟,见代码。
代码:
#include
#include
#include
#include
#include
using namespace std;
const int MAXN=1010;
int T,n,L,K,gol[MAXN],x[MAXN],y[MAXN];
int q[MAXN],l,r;
bool used[MAXN];
bool cmp(int i,int j)
{
return x[i]r) break;
if(nowy+nowx-x[q[l]]=l&&x[q[r]]+y[q[r]]<=nowx+nowy) r--;
if(l>r) break;
}
if(ok) ans=min(ans,nowy+abs(nowx-K));
}
printf("%d\n",ans);
}
return 0;
}
E:Half-consecutive Numbers
题意:定义序列t[i]=i*(i+1)/2,每次给定一个n,问t序列第n项以后的第一个完全平方数是什么,n<=10^16。
题解:i和i+1/2互质,故要么i=n^2, i+1=2m^2,或者i=2m^2, i+1=n^2。枚举n,n不超过10^8, 打表。
代码:
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long LL;
bool test(LL x){
LL r=sqrt(x+0.5);
return r*r==x;
}
bool check(LL n,LL k){
LL m=n*n+k;
return test(m/2);
}
LL lis[100]={0LL,1LL,8LL,49LL,288LL,1681LL,9800LL,57121LL,332928LL,1940449LL,11309768LL,65918161LL,384199200LL,2239277041LL,13051463048LL,76069501249LL,443365544448LL,2584123765441LL,15061377048200LL,87784138523761LL,511643454094368LL,2982076586042449LL,17380816062160328LL,};
int main(){
/*freopen("ilis.out","w",stdout);
LL mx=1e16;
cout<=mx) break;
}
if(check(i,1)){
cout<=mx) break;
}
}*/
int T;scanf("%d",&T);
for(int tot=1;tot<=T;tot++){
LL n;scanf("%lld",&n);
int i;for(i=0;lis[i]
F:Islands
题解:缩点之后,所有块的入度、出度取max。
代码:
#include
G:Query on String
题意:给字符串S,T,T的长度不超过10.每次询问S[l..r]中有多少个T,或者改S的一位。
题解:先预处理一下,就变成了区间和查询。改S的一位至多影响10个值,用树状数组即可。
代码:
#include
H:Skiing
题意:DAG最长路。DAG是题目保证的……
题解:随便写。我抄了个SPFA的板子。
代码:
#include
#include
#include
#include
#include
#include
using namespace std;
const int INF=0x7fffffff/2;
const int SIZEN=10010;
int N,M;
vector > c[SIZEN];
void SPFA(vector > c[SIZEN],int N,int S,int f[SIZEN]){//图中顶点0~N-1,邻接表为c,以S出发,结果存于f
queue Q;
bool inq[SIZEN]={0};
for(int i=0;i<=N+1;i++) f[i]=-INF;
f[S]=0,inq[S]=true,Q.push(S);
while(!Q.empty()){
int x=Q.front();Q.pop();inq[x]=false;
for(int i=0;if[u]){
f[u]=f[x]+c[x][i].second;
if(!inq[u]){
inq[u]=true;
Q.push(u);
}
}
}
}
}
int f[SIZEN];
void work(void){
SPFA(c,N,0,f);
printf("%d\n",f[N+1]);
}
void read(void){
scanf("%d%d",&N,&M);
int a,b,w;
for(int i=0;i<=N+1;i++) c[i].clear();
for(int i=1;i<=M;i++){
scanf("%d%d%d",&a,&b,&w);
c[a].push_back(make_pair(b,w));
}
for(int i=1;i<=N;i++){
c[0].push_back(make_pair(i,0));
c[i].push_back(make_pair(N+1,0));
}
}
int main(){
int T;scanf("%d",&T);
while(T--){
read();
work();
}
return 0;
}
I:Colored Graph
题意:给一张N个点完全图,求把每条边黑白染色,最少生成多少个纯色三角形。
代码:
#include
#include
#include
#include
using namespace std;
int T,n;
int d[510][510],a[510];
int gcd(int a,int b)
{
if(b==0) return a;
return gcd(b,a%b);
}
void print()
{
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
printf("%d",d[i][j]);
if(j!=n) putchar(' ');
else printf("\n");
}
}
int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
if(n%2==0)
{
for(int i=1;i<=n/2;i++)
for(int j=1;j<=n/2;j++)
if(i!=j) d[i][j]=2;
for(int i=n/2+1;i<=n;i++)
for(int j=n/2+1;j<=n;j++)
if(i!=j) d[i][j]=2;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(i!=j&&d[i][j]==0) d[i][j]=1;
}
else if(n%4==1)
{
int total=0;
for(int i=1;i
J:Our Journey of Dalian Ends
题意:一张无向图,求从1走到N,必须经过K,每个节点至多经过一次的最短路。
题解:费用流。
代码:
#include
#include
#include
#include
#include
#include