A. Rank List
大水题,求第K名有几人和它的分数一样,考察结构体排序
代码:
#include <iostream>
#include <cstring>
#include <map>
#include <cmath>
#include <stack>
#include <vector>
#include <algorithm>
#include <stdio.h>
using namespace std;
const int M=50000;
struct node
{
int pi,ti;
int id;
} a[55];
int b[55];
bool cmp(node a,node b)
{
if(a.pi==b.pi)
return a.ti<b.ti;
return a.pi>b.pi;
}
int main()
{
int n,k;
scanf("%d%d",&n,&k);
for(int i=0; i<n; i++)
{
scanf("%d %d",&a[i].pi,&a[i].ti);
}
sort(a,a+n,cmp);
int ans=0;
for(int i=0;i<n;i++)
{
if(a[i].pi==a[k-1].pi && a[i].ti==a[k-1].ti)
ans++;
}
printf("%d\n",ans);
return 0;
}
B. Polygons
题意:给出两个凸多边形A、B,判断B是否严格在A凸多变形内,严格B不能和A有交点凸包问题,WA了好多次,就是一个精度问题。。先进行特殊判断,先排序,只要发现有两个点相同,那肯定不符合
代码:
#include <iostream>//B
#include <cstring>
#include <map>
#include <cmath>
#include <stack>
#include <vector>
#include <algorithm>
#include <stdio.h>
using namespace std;
const int M=100005;
struct node
{
int x,y;
int belong;
} a[2*M];
node stak[2*M];
int n,m;
bool cmp(node a,node b)
{
if(a.x==b.x)return a.y<b.y;
return a.x<b.x;
}
long long dis(node a,node b,node c)
{
return (long long)(b.x-a.x)*(c.y-a.y)-(long long)(c.x-a.x)*(b.y-a.y);
//return (b.x-a.x)*(c.y-b.y)-(c.x-b.x)*(b.y-a.y);
}
int main()
{
scanf("%d",&n);
for(int i=1; i<=n; i++)
{
scanf("%d%d",&a[i].x,&a[i].y);
a[i].belong=1;
}
scanf("%d",&m);
for(int i=n+1; i<=m+n; i++)
{
scanf("%d%d",&a[i].x,&a[i].y);
a[i].belong=2;
}
sort(a+1,a+m+n+1,cmp);
for(int i=2; i<=n+m; i++)
{
if(a[i].x==a[i-1].x && a[i].y==a[i-1].y)
{
cout<<"NO"<<endl;
return 0;
}
}
int s;
stak[1]=a[1];
stak[2]=a[2];
s=2;
for(int i=3; i<=n+m; i++)
{
while(s>1 && dis(stak[s-1],stak[s],a[i])<0)s--;
stak[++s]=a[i];
}
int len = s;
stak[++s] = a[n+m-1];
for(int i = n+m-2; i >0; --i)
{
while(s!=len && dis(stak[s-1],stak[s],a[i])<0)s--;
stak[++s]=a[i];
}
for(int i=1; i<=s; i++)
{
if(stak[i].belong==2)
{
cout<<"NO"<<endl;
return 0;
}
}
cout<<"YES"<<endl;
return 0;
}
C. Median
题意:求应该在原数组里最少增加几个数是的所给X在原数组排序后处于中间mid=(n+1)/2处。。这题还是得手动列一下,就会发现一些规律(还算得上吧),先看原数组里有没有X,没有有的话先加X到末尾在进行从小到大排序,找X的位置i,若i==mid,cnt=1;我们可以发现2*i<2*mid=n(n%2==0),2*i-1<2*mid-1=n(n%2==1),要使i为中心位置,就以i为中心取2*i个数,因为i<mid,右边肯定会多出几个数,为了平衡,应该也在左边多出和右边一样多的数,即cnt+=2*mid-2*i=n-2*i;同理:i>mid,2*i>2*mid,cnt+=2*i-2*mid-1=2*i-n-1,减1是为了是的所加数最小,举个例子5 和6,中心位置都是3,那我们就要5,也就是取奇数。
代码:
#include <iostream>
#include <cstring>
#include <map>
#include <cmath>
#include <stack>
#include <vector>
#include <algorithm>
#include <stdio.h>
using namespace std;
int a[505];
int main()
{
int n,x,i,ans=0;
scanf("%d%d",&n,&x);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
for(i=1;i<=n;i++)
{
if(a[i]==x)break;
}
if(i==n+1)
{
ans++;
n++;
a[n]=x;
}
sort(a+1,a+n+1);
int mid=(n+1)>>1;
if(a[mid]<x)
{
for(i=mid+1;i<=n;i++)
{
if(a[i]==x)break;
}
ans+=2*i-n-1;
}
if(a[mid]>x)
{
for(i=mid-1;i>=1;i--)
if(a[i]==x)break;
ans+=n-2*i;
}
cout<<ans<<endl;
return 0;
}
E. Tetrahedron
推规律题,但是当时赛场上我就没有推出,有点拙了,附上一个DP的代码吧
#include <iostream>
#include <cstring>
#include <map>
#include <cmath>
#include <stack>
#include <vector>
#include <algorithm>
#include <stdio.h>
using namespace std;
const int M=50000;
const int N=1e9+7;
int dp[10000007][4];
int main()
{
dp[0][0]=1;
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
dp[i][0]=(dp[i-1][1]+(dp[i-1][2]+dp[i-1][3])%N)%N;
dp[i][1]=(dp[i-1][0]+(dp[i-1][2]+dp[i-1][3])%N)%N;
dp[i][2]=(dp[i-1][0]+(dp[i-1][1]+dp[i-1][3])%N)%N;
dp[i][3]=(dp[i-1][0]+(dp[i-1][1]+dp[i-1][2])%N)%N;
}
cout<<dp[n][0]<<endl;
return 0;
}