A. 游戏
只要枚举边上的角度即可, 使用点乘可以轻松判断
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <cmath>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <algorithm>
#include <climits>
#define MAXN 100005
#define eps 1e-5
#define MOD 1000000009
#define test
#define For(i,m,n) for(int i=(m);i<(n);i++)
#define vecfor(iter,a) for(vector<int>::iterator iter=a.begin();iter!=a.end();iter++)
#define rep(i,m,n) for(int i=(m);i<=(n);i++)
#define LL long long
/*author birdstorm*/
using namespace std;
const double pi=acos(-1.0);
double a[1111][3];
double cross(double x1, double y1, double x2, double y2)
{
return x1*x2+y1*y2;
}
int main()
{
//freopen("input.txt","r",stdin);
int n, m;
int cnt=0;
while(~scanf("%d",&n)){
For(i,0,n) scanf("%lf%lf",&a[i][0], &a[i][1]);
a[n][0]=a[0][0], a[n][1]=a[0][1];
a[n+1][0]=a[1][0], a[n+1][1]=a[1][1];
a[n+2][0]=a[2][0], a[n+2][1]=a[2][1];
int cnt=n;
For(i,0,n){
double x1=a[i][0]-a[i+1][0];
double y1=a[i][1]-a[i+1][1];
double x2=a[i+1][0]-a[i+2][0];
double y2=a[i+1][1]-a[i+2][1];
double x3=a[i+2][0]-a[i+3][0];
double y3=a[i+2][1]-a[i+3][1];
if(cross(x1,y1,x2,y2)<=eps&&cross(x2,y2,x3,y3)<=eps) cnt--;
}
printf("%d\n",cnt);
}
return 0;
}
B. 小妹妹送快递
题意要求的是s-t路径上最大边权的最小值
将边从小到大排序后, 依次连边建图.
最后直接并查集查找即可
要注意即使路径上最小边权为0, 也必须使用一个小妹妹送快递
所以需要特判.
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <cmath>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <algorithm>
#include <climits>
#define MAXN 100005
#define eps 1e-5
#define MOD 1000000009
#define INF 1000000009
#define test
#define For(i,m,n) for(int i=(m);i<(n);i++)
#define vecfor(iter,a) for(vector<int>::iterator iter=a.begin();iter!=a.end();iter++)
#define rep(i,m,n) for(int i=(m);i<=(n);i++)
#define LL long long
/*author birdstorm*/
using namespace std;
const double pi=acos(-1.0);
template<class T>
inline bool read(T &n){
T x=0, tmp=1; char c=getchar();
while((c < '0' || c > '9') && c != '-' && c != EOF) c=getchar();
if(c == EOF) return false;
if(c == '-') c=getchar(), tmp=-1;
while(c >= '0' && c <= '9') x *= 10, x += (c - '0'),c=getchar();
n=x*tmp;
return true;
}
template <class T>
inline void write(T n) {
if(n < 0) {
putchar('-');
n=-n;
}
int len=0,data[20];
while(n) {
data[len++]=n%10;
n /= 10;
}
if(!len) data[len++]=0;
while(len--) putchar(data[len]+48);
}
pair<pair<int,int>,int> edge[200005];
LL a[MAXN];
int vis[MAXN];
struct Disjoint{
vector<int> father,rank;
Disjoint(int n):father(n),rank(n){
For(i,0,n) father[i]=i;
}
int find(int v){
return father[v]=father[v]==v?v:find(father[v]);
}
void merge(int x,int y){
int a=find(x), b=find(y);
if(a==b) return;
if(rank[a]<rank[b]){
father[a]=b;
}
else{
father[b]=a;
if(rank[b]==rank[a]) ++rank[a];
}
}
void clear(int n){
For(i,0,n) father[i]=i, rank[i]=0;
}
};
bool cmp(pair<pair<int,int>,int> a, pair<pair<int,int>,int> b)
{
return a.second<b.second;
}
int main()
{
//freopen("input.txt","r",stdin);
//freopen("output.txt","w",stdout);
int u, v, w;
Disjoint D(MAXN);
int n, m;
int t;
scanf("%d",&t);
while(t--){
read(n),read(m);
int ans=0;
int tot=0;
D.clear(n+1);
For(i,0,m){
read(u),read(v),read(w);
edge[tot++]=make_pair(make_pair(u,v),w);
}
sort(edge,edge+tot,cmp);
//For(i,0,tot) printf("%d %d %d--\n",edge[i].first.first,edge[i].first.second,edge[i].second);
bool found=false;
For(i,0,tot){
D.merge(edge[i].first.first,edge[i].first.second);
if(D.find(1)==D.find(n)){
printf("%d\n",max(1,edge[i].second));
//printf("%d\n",i);
found=true;
break;
}
}
if(!found) printf("shimatta!\n");
}
return 0;
}
C. 学姐点名
签到题, 有代码长度限制.....所以姿势比较难看.(其实没必要
#include <cstdio>
int main(){long long n, a, sum; while(~scanf("%lld",&n)) { sum=n*(n+1)/2; for(int i=0; i<n-1; i++) scanf("%lld",&a), sum-=a; printf("%lld\n",sum);} return 0;}
D. 解码锦标赛
模拟, 下标太乱了导致当时没调出来...
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <cmath>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <algorithm>
#include <climits>
#define MAXN 100005
#define eps 1e-5
#define MOD 1000000009
#define test
#define For(i,m,n) for(int i=(m);i<(n);i++)
#define vecfor(iter,a) for(vector<int>::iterator iter=a.begin();iter!=a.end();iter++)
#define rep(i,m,n) for(int i=(m);i<=(n);i++)
#define LL long long
/*author birdstorm*/
using namespace std;
const double pi=acos(-1.0);
double a[3000][3000];
double dp[3000][3000];
int main()
{
//freopen("input.txt","r",stdin);
int n, m;
int f[10]; f[0]=1;
For(i,1,10) f[i]=f[i-1]*2;
while(scanf("%d",&n),n){
int cnt=0;
For(i,0,f[n]) dp[i][0]=1;
For(i,0,f[n]) For(j,0,f[n]) scanf("%lf",&a[i][j]);
For(i,1,n+1){
For(j,0,f[n]){
dp[j][i]=dp[j][i-1];
double ans=0;
int st=(j/f[i-1])^1;
st=st*f[i-1];
int en=st+f[i-1];
//printf("%d %d %d\n",st,en-1,j);
For(k,st,en){
//if(k==j) continue;
ans+=dp[k][i-1]*a[j][k];
//printf("%d\n",k);
}
dp[j][i]*=ans;
}
}
int ret=0;
double maxx=0;
For(i,0,f[n]){
//printf("%lf ",dp[i][n]);
if(maxx<dp[i][n]){
maxx=dp[i][n];
ret=i+1;
}
}
printf("%d\n",ret);
}
return 0;
}
E. 田田的算数题
线段树维护两个域: 首项和公差. 查询时使用懒标记