第八届福建省赛训练总结 【6/12】
来源:互联网 发布:查看linux内核 编辑:程序博客网 时间:2024/05/10 09:20
这场6题,不过罚时有点炸,不符合我们的队以往的作风。。剩下的题有点算法有点涉及到我们的盲区了...继续努力把~
1 Frog
————————————————————————————————————
水2 Triangles
————————————————————————————————————
给你两个三角形,问你这两个三角形是包含的,还是相交的,还是相离的。
其实是一个jianda
#include <iostream>#include <cstring>#include <cstdio>#include <algorithm>#include <cmath>#include <map>using namespace std;const double eps = 1e-6;int sgn(double x){ if(fabs(x) < eps)return 0; if(x < 0)return -1; else return 1;}struct Point{ double x,y; Point(){} Point(double _x,double _y) { x = _x;y = _y; } Point operator -(const Point &b)const { return Point(x - b.x,y - b.y); } double operator ^(const Point &b)const { return x*b.y - y*b.x; } double operator *(const Point &b)const { return x*b.x + y*b.y; } void transXY(double B) { double tx = x,ty = y; x = tx*cos(B) - ty*sin(B); y = tx*sin(B) + ty*cos(B); }};struct Line{ Point s,e; Line(){} Line(Point _s,Point _e) { s = _s;e = _e; } pair<int,Point> operator &(const Line &b)const { Point res = s; if(sgn((s-e)^(b.s-b.e)) == 0) { if(sgn((s-b.e)^(b.s-b.e)) == 0) return make_pair(0,res); else return make_pair(1,res); } double t = ((s-b.s)^(b.s-b.e))/((s-e)^(b.s-b.e)); res.x += (e.x-s.x)*t; res.y += (e.y-s.y)*t; return make_pair(2,res); }};bool inter(Line l1,Line l2){ return max(l1.s.x,l1.e.x) >= min(l2.s.x,l2.e.x) && max(l2.s.x,l2.e.x) >= min(l1.s.x,l1.e.x) && max(l1.s.y,l1.e.y) >= min(l2.s.y,l2.e.y) && max(l2.s.y,l2.e.y) >= min(l1.s.y,l1.e.y) && sgn((l2.s-l1.e)^(l1.s-l1.e))*sgn((l2.e-l1.e)^(l1.s-l1.e)) <= 0 && sgn((l1.s-l2.e)^(l2.s-l2.e))*sgn((l1.e-l2.e)^(l2.s-l2.e)) <= 0;}bool OnSeg(Point P,Line L){ return sgn((L.s-P)^(L.e-P)) == 0 && sgn((P.x - L.s.x) * (P.x - L.e.x)) <= 0 && sgn((P.y - L.s.y) * (P.y - L.e.y)) <= 0;}int inConvexPoly(Point a,Point p[],int n){ for(int i = 0;i < n;i++) { if(sgn((p[i]-a)^(p[(i+1)%n]-a)) < 0)return -1; else if(OnSeg(a,Line(p[i],p[(i+1)%n])))return 0; } return 1;}int inPoly(Point p,Point poly[],int n){ int cnt; Line ray,side; cnt = 0; ray.s = p; ray.e.y = p.y; ray.e.x = -100000000000.0; for(int i = 0;i < n;i++) { side.s = poly[i]; side.e = poly[(i+1)%n]; if(OnSeg(p,side))return 0; //如果平行轴则不考虑 if(sgn(side.s.y - side.e.y) == 0) continue; if(OnSeg(side.s,ray)) { if(sgn(side.s.y - side.e.y) > 0)cnt++; } else if(OnSeg(side.e,ray)) { if(sgn(side.e.y - side.s.y) > 0)cnt++; } else if(inter(ray,side)) cnt++; } if(cnt % 2 == 1)return 1; else return -1;}int main(){ int t; cin >> t; int x1, x2, x3, x4, x5, x6, y1,y2,y3,y4,y5,y6; while(t--) { scanf("%d%d%d%d%d%d", &x1, &y1, &x2, &y2, &x3, &y3); scanf("%d%d%d%d%d%d", &x4, &y4, &x5, &y5, &x6, &y6); Point p1[10], p2[10];// if(x1 > x2) swap(x1, x2);// if(y1 > y2) swap(y1, y2);// if(x1 > x3) swap(x1, x3);// if(y1 > y3) swap(y1, y3);// if(x2 > x3) swap(x2, x3);// if(y2 > y3) swap(y2, y3); p1[0] = Point(x1, y1); p1[1] = Point(x2, y2); p1[2] = Point(x3, y3);// if(x4 > x5) swap(x4, x5);// if(y4 > y5) swap(y4, y5);// if(x4 > x6) swap(x4, x6);// if(y4 > y6) swap(y4, y6);// if(x5 > x6) swap(x5, x6);// if(y5 > y6) swap(y5, y6); p2[0] = Point(x4, y4); p2[1] = Point(x5, y5); p2[2] = Point(x6, y6); int flag = 0; if(inPoly(p1[0], p2, 3) == 1 && inPoly(p1[1], p2, 3) == 1 && inPoly(p1[2], p2, 3) == 1) flag = 1; if(inPoly(p2[0], p1, 3) == 1 && inPoly(p2[1], p1, 3) == 1 && inPoly(p2[2], p1, 3) == 1) flag = 1; for(int i = 0; i < 3; i++) { for(int j = i; j < 3; j++) { Line l1 = Line(p1[i], p1[j]); for(int x = 0; x < 3; x++) { for(int y = x; y < 3; y++) { Line l2 = Line(p2[x], p2[y]); if(inter(l1, l2)) flag = 2; } } } } if(flag == 1) puts("contain"); else if(flag == 2) puts("intersect"); else puts("disjoint"); } return 0;}/*104 3 7 3 7 65 2 5 10 6 10*/
3 DotA and LOL
————————————————————————————————————
4 Game
————————————————————————————————————
给你两个大数,(不含前导零),
两个人轮流操作自己的数,可以除以10(向下取整,没有小数.)或者翻转过去,(翻转之后要去掉前导0).
当有一时刻两个数相等则A赢,否则B赢,所以A想要将两个数变得相同,B想讲两个数变得不同.
问你两个人最后谁赢?
可以考虑一下,因为每一轮每人必须要对自己的数进行一次操作,直到最后为0,也一直在进行,一直是0了.
所以我们可以想到,如果当前B不能在A中正着匹配,或者反着匹配,那么无论A怎么变我B就一直翻转我的数,那你永远
也别想赢.否则如果A中有B的子串,那你B无论怎么办,总有一个A==B ,上面也说了即使除到0,最后就真的一直是0
俩人都是0也匹配了.
另外需要注意,如果一开始B后面有0,需要将B中的后缀0 全部去掉,在跟A进行匹配.但是A中后面的0对结果无影响.
举例: 1235 120
#include <iostream>#include <algorithm>#include <stdio.h>#include <string.h>#include <queue>#define maxs 2020202#define mme(i,j) memset(i,j,sizeof(i))using namespace std;char s[1000005],s2[1000005];int nexts[maxs];void getn(){ int len=strlen(s2); int i=0,j; j=nexts[0]=-1; for(i=0;i<len;) { if(j==-1 || s2[i]==s2[j]) nexts[++i]=++j; else j=nexts[j]; }}bool kmp(){ getn(); int len1=strlen(s),len2=strlen(s2); int i=0,j=0; for(i=0;i<len1;) { if(j==-1||s[i]==s2[j]) { i++; j++; } else j=nexts[j]; if(j>=len2) return 1; } if(j>=len2) return 1; return 0;}int main(){ int t; scanf("%d",&t); while(t--) { scanf("%s%s",s,s2); int flag = 1; for(int i=0;s2[i];i++){ if(s2[i]=='0') continue; flag = 0 ;break; } int l2 = strlen(s2); for(int i=l2-1;i>=0;i--){ if(s2[i]=='0') s2[i]='\0'; else break; }// puts(s2); if(flag||kmp()) { printf("Alice\n"); } else { reverse(s2,s2+strlen(s2)); if(kmp()) { printf("Alice\n"); } else printf("Bob\n"); } }}
5 Doctor
————————————————————————————————————
6 Change
————————————————————————————————————
7 YYS
————————————————————————————————————
就是有一个人,要集齐n张卡,每个卡出现的概率都为1/n,他每隔w天可以买一次卡,问你集齐所有卡片的期望是多少.
主要是数太大了- -,最后化简是 n!/i, i 从1 到 n, 找了一大堆大数模板,最后才找到一个不错的,概率dp+大数把
#include <iostream>#include <cstdio>#include <algorithm>#include <string>#include <cmath>#include <stack>#include <cstring>using namespace std;//const int maxn = 1e6; //大数位数#define MAXN 9999#define MAXSIZE 10#define DLEN 4class BigNum{private: int a[MAXN]; //可以控制大数的位数 int len; //大数长度public: BigNum(){ len = 1;memset(a,0,sizeof(a)); } //构造函数 BigNum(const int); //将一个int类型的变量转化为大数 BigNum(const char*); //将一个字符串类型的变量转化为大数 BigNum(const BigNum &); //拷贝构造函数 BigNum &operator=(const BigNum &); //重载赋值运算符,大数之间进行赋值运算 friend istream& operator>>(istream&, BigNum&); //重载输入运算符 friend ostream& operator<<(ostream&, BigNum&); //重载输出运算符 BigNum operator+(const BigNum &) const; //重载加法运算符,两个大数之间的相加运算 BigNum operator-(const BigNum &) const; //重载减法运算符,两个大数之间的相减运算 BigNum operator*(const BigNum &) const; //重载乘法运算符,两个大数之间的相乘运算 BigNum operator/(const int &) const; //重载除法运算符,大数对一个整数进行相除运算 BigNum operator^(const int &) const; //大数的n次方运算 int operator%(const int &) const; //大数对一个int类型的变量进行取模运算 bool operator>(const BigNum & T)const; //大数和另一个大数的大小比较 bool operator<(const BigNum & T) const; bool operator==(const BigNum & T) const; bool operator>(const int & t)const; //大数和一个int类型的变量的大小比较 bool operator<(const int &t) const; bool operator==(const int &t) const; void print(); //输出大数};bool BigNum::operator==(const BigNum & T) const { return !(*this > T) && !(T > *this);}bool BigNum::operator==(const int &t) const { BigNum T = BigNum(t); return *this == T;}bool BigNum::operator<(const BigNum & T) const { return T > *this;}bool BigNum::operator<(const int &t) const { return BigNum(t) > *this;}BigNum::BigNum(const int b) //将一个int类型的变量转化为大数{ int c,d = b; len = 0; memset(a,0,sizeof(a)); while(d > MAXN) { c = d - (d / (MAXN + 1)) * (MAXN + 1); d = d / (MAXN + 1); a[len++] = c; } a[len++] = d;}BigNum::BigNum(const char*s) //将一个字符串类型的变量转化为大数{ int t,k,index,l,i; memset(a,0,sizeof(a)); l=strlen(s); len=l/DLEN; if(l%DLEN) len++; index=0; for(i=l-1;i>=0;i-=DLEN) { t=0; k=i-DLEN+1; if(k<0) k=0; for(int j=k;j<=i;j++) t=t*10+s[j]-'0'; a[index++]=t; }}BigNum::BigNum(const BigNum & T) : len(T.len) //拷贝构造函数{ int i; memset(a,0,sizeof(a)); for(i = 0 ; i < len ; i++) a[i] = T.a[i];}BigNum & BigNum::operator=(const BigNum & n) //重载赋值运算符,大数之间进行赋值运算{ int i; len = n.len; memset(a,0,sizeof(a)); for(i = 0 ; i < len ; i++) a[i] = n.a[i]; return *this;}istream& operator>>(istream & in, BigNum & b) //重载输入运算符{ char ch[MAXSIZE*4]; int i = -1; in>>ch; int l=strlen(ch); int count=0,sum=0; for(i=l-1;i>=0;) { sum = 0; int t=1; for(int j=0;j<4&&i>=0;j++,i--,t*=10) { sum+=(ch[i]-'0')*t; } b.a[count]=sum; count++; } b.len =count++; return in;}ostream& operator<<(ostream& out, BigNum& b) //重载输出运算符{ int i; cout << b.a[b.len - 1]; for(i = b.len - 2 ; i >= 0 ; i--) { cout.width(DLEN); cout.fill('0'); cout << b.a[i]; } return out;}BigNum BigNum::operator+(const BigNum & T) const //两个大数之间的相加运算{ BigNum t(*this); int i,big; //位数 big = T.len > len ? T.len : len; for(i = 0 ; i < big ; i++) { t.a[i] +=T.a[i]; if(t.a[i] > MAXN) { t.a[i + 1]++; t.a[i] -=MAXN+1; } } if(t.a[big] != 0) t.len = big + 1; else t.len = big; return t;}BigNum BigNum::operator-(const BigNum & T) const //两个大数之间的相减运算{ int i,j,big; bool flag; BigNum t1,t2; if(*this>T) { t1=*this; t2=T; flag=0; } else { t1=T; t2=*this; flag=1; } big=t1.len; for(i = 0 ; i < big ; i++) { if(t1.a[i] < t2.a[i]) { j = i + 1; while(t1.a[j] == 0) j++; t1.a[j--]--; while(j > i) t1.a[j--] += MAXN; t1.a[i] += MAXN + 1 - t2.a[i]; } else t1.a[i] -= t2.a[i]; } t1.len = big; while(t1.a[t1.len - 1] == 0 && t1.len > 1) { t1.len--; big--; } if(flag) t1.a[big-1]=0-t1.a[big-1]; return t1;}BigNum BigNum::operator*(const BigNum & T) const //两个大数之间的相乘运算{ BigNum ret; int i,j,up; int temp,temp1; for(i = 0 ; i < len ; i++) { up = 0; for(j = 0 ; j < T.len ; j++) { temp = a[i] * T.a[j] + ret.a[i + j] + up; if(temp > MAXN) { temp1 = temp - temp / (MAXN + 1) * (MAXN + 1); up = temp / (MAXN + 1); ret.a[i + j] = temp1; } else { up = 0; ret.a[i + j] = temp; } } if(up != 0) ret.a[i + j] = up; } ret.len = i + j; while(ret.a[ret.len - 1] == 0 && ret.len > 1) ret.len--; return ret;}BigNum BigNum::operator/(const int & b) const //大数对一个整数进行相除运算{ BigNum ret; int i,down = 0; for(i = len - 1 ; i >= 0 ; i--) { ret.a[i] = (a[i] + down * (MAXN + 1)) / b; down = a[i] + down * (MAXN + 1) - ret.a[i] * b; } ret.len = len; while(ret.a[ret.len - 1] == 0 && ret.len > 1) ret.len--; return ret;}int BigNum::operator %(const int & b) const //大数对一个int类型的变量进行取模运算{ int i,d=0; for (i = len-1; i>=0; i--) { d = ((d * (MAXN+1))% b + a[i])% b; } return d;}BigNum BigNum::operator^(const int & n) const //大数的n次方运算{ BigNum t,ret(1); int i; if(n<0) exit(-1); if(n==0) return 1; if(n==1) return *this; int m=n; while(m>1) { t=*this; for( i=1;i<<1<=m;i<<=1) { t=t*t; } m-=i; ret=ret*t; if(m==1) ret=ret*(*this); } return ret;}bool BigNum::operator>(const BigNum & T) const //大数和另一个大数的大小比较{ int ln; if(len > T.len) return true; else if(len == T.len) { ln = len - 1; while(a[ln] == T.a[ln] && ln >= 0) ln--; if(ln >= 0 && a[ln] > T.a[ln]) return true; else return false; } else return false;}bool BigNum::operator >(const int & t) const //大数和一个int类型的变量的大小比较{ BigNum b(t); return *this>b;}void BigNum::print() //输出大数{ int i; printf("%d", a[len-1]); for (int i = len-2; i >= 0; --i) { printf("%04d", a[i]); }}int main(){ int t, n; cin >> t; while(t--) { scanf("%d", &n); BigNum cnt = 1, ans = 0; for(int i = 1; i <= n; i++) { cnt = cnt * i; }; for(int i = 1; i <= n; i++) { ans = ans + cnt/i;; BigNum tmp = (cnt/i); } ans.print(); printf(".0\n"); } return 0;}
8 Cantonese
————————————————————————————————————
9 Magic
————————————————————————————————————
10 Trades
————————————————————————————————————
11 Wand
————————————————————————————————————
有n个人,每个人有一个物品,问你打乱这些物品后至少有K个人还拿到自己的物品的可能数
水题, 但是我tm还是wa了一发。。 爆了long long;
枚举k, 然后剩下的错排就好了, 这题应该n再大一点2e7左右, 因为k就100, 很明显暗示我们要将“至少“转化...可是这题没卡
代码转自tabris
#include<stdio.h>#include<string.h>using namespace std;#define LL long long intconst int N = 1e5 + 7;const int MOD = 1e9+7;/**********************************/LL qmod(LL a,LL b) { LL res = 1ll; while(b) { if(b&1) res=res*a%MOD; b>>=1,a=a*a%MOD; } return res;}LL dp[N];LL fac[N],inv[N];void init() { fac[0]=1; for(LL i=1; i<N; i++) fac[i]=(fac[i-1]*i)%MOD; inv[N-1] = qmod(fac[N-1],MOD-2); for(LL i=N-2; i>=0; i--) inv[i]=(inv[i+1]*(i+1))%MOD;}LL C(int n,int m) { return fac[n]*inv[m]%MOD*inv[n-m]%MOD;}int main() { init(); dp[0]=1; dp[1]=0; for(LL i=1; i<=10000; i++) { dp[i]=(i-1)*(dp[i-1]+dp[i-2]); dp[i]%=MOD; } int t; int n,kk; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&kk); LL output=0; for(int k=kk; k<=n; k++) { output+=C(n,k)*dp[n-k]%MOD; output%=MOD; } printf("%I64d\n",output%MOD); } return 0;}
12 Tic-Tac-Toe
————————————————————————————————————
两个人下井字棋,现在轮到Kim下,问你Kim在下两个子的内能不能赢
- 第八届福建省赛训练总结 【6/12】
- 第八届福建省大学生程序设计竞赛训练总结【7/12】
- 第八届福建省省赛重现 7/12 待补
- 第八届福建省赛-重现赛 【(6+3)/12】 [待补]
- Tic-Tac-Toe (第八届福建省赛)
- 2017第八届福建省大学生程序设计竞赛总结
- 第八场训练赛总结
- 第八届福建省大学生程序设计竞赛-重现赛 A Frog
- 第八届福建省大学生程序设计竞赛-重现赛I Magic
- 7.22.17 第八届福建省大学生程序设计竞赛-重现赛
- 第八届福建省大学生程序设计竞赛 省赛回忆
- 2017第八届山东省赛训练总结2017/5/9
- 福建省第八届程序设计大赛专题
- 第八届福建省大学生程序设计竞赛
- 第八届福建省大学生程序设计竞赛-重现赛 L Tic-Tac-Toe
- 第八届福建省大学生程序设计竞赛-重现赛(A+D+K+L)
- 第八届福建省大学生程序设计竞赛 重现赛 第二题 Triangles
- 第八届福建省大学生程序设计竞赛-重现赛(感谢承办方厦门理工学院)
- angular的同级controller通信
- 测试自动化_快速定位元素_生成模板_web篇
- Count the Trees(卡特蘭數)
- 判断是否是栈的弹出序列&&二进制中1的个数
- dubbo+spring+zookeeper的集成入门实例
- 第八届福建省赛训练总结 【6/12】
- 1002·实数运算2
- springmvc的REST_CRUD
- apache-comnons系列之commons-collections4 org.apache.commons.collections4.CollectionUtils学习笔记
- 【redis】Redis
- CUDA之计算模式
- linux配置ssh免密登录
- 回忆录
- Activity的启动和关闭方法