福州大学7.22 多校模拟赛

T2 三角形位置判断

最佳算法:判断三角形的各个点是否都在第二个三角形内

#include <cstdio>

#include <iostream>
#include <cstring>
#include <algorithm>
#include <stack>
#include <string>
using namespace std;


struct point
{
    int x,y;
};
struct vec
{
    int x,y;
};
bool intersect(point v1,point v2,point v3,point v4)
{
    int d = (v4.y-v3.y)*(v2.x-v1.x)-(v4.x-v3.x)*(v2.y-v1.y);
    int u = (v4.x-v3.x)*(v1.y-v3.y)-(v4.y-v3.y)*(v1.x-v3.x);
    int v = (v2.x-v1.x)*(v1.y-v3.y)-(v2.y-v1.y)*(v1.x-v3.x);
    if(d<0)
    {
        u*=-1; d*=-1; v*=-1;
    }
    return (0<=u && u<=d)&&(0<=v && v<=d);
}
int cross(vec v1,vec v2)
{
    return (v1.x*v2.y -v1.y*v2.x);
}
vec setvec(point f,point t)
{
    vec temp={t.x-f.x,t.y-f.y};
    return temp;
}
bool leftside(point f,point t,point p)
{
    vec ft={t.x-f.x,t.y-f.y};
    vec fp={p.x-f.x,p.y-f.y};
    return (cross(ft,fp)<0);
}
int main(int argc, char const *argv[])
{
    int t;
    cin>>t;
    while(t--)
    {
        point tra[2][3];
        for(int i=0;i<3;++i) scanf("%d%d",&tra[0][i].x,&tra[0][i].y);
        for(int i=0;i<3;++i) scanf("%d%d",&tra[1][i].x,&tra[1][i].y);
        bool not_intersect=1;
        for(int i=0;i<3 && not_intersect;++i)
            for(int j=0;j<3 && not_intersect;++j)
                if(intersect(tra[0][i],tra[0][(i+1)%3],tra[1][j],tra[1][(j+1)%3]))
                    not_intersect=0;
        if(!not_intersect)
        {
            printf("intersect\n");
            continue;
        }
        bool inside[2]={1,1};
        for (int i = 0; i < 2; ++i)
        {
            if(leftside(tra[i][0],tra[i][1],tra[i][2]))
            {
                for(int j=0;j<3;++j)
                    for(int k=0;k<3;++k)
                        if(!leftside(tra[i][j],tra[i][(j+1)%3],tra[!i][k]))
                            inside[i]=0;
            }else{
                for(int j=2;j>=0;--j)
                    for(int k=0;k<3;++k)
                        if(!leftside(tra[i][j],tra[i][(j+2)%3],tra[!i][k]))
                            inside[i]=0;           
            }
        }
        if(inside[0] || inside[1])
            printf("contain\n");
        else printf("disjoint\n");
    }  

}

T4 KMP+博弈论

#include <cstdio>
#include <cstring>
#include <cmath>
#include <queue>
#include <algorithm>
#include <cctype>
#include <vector>
#include <map>
#include <set>
using namespace std;
typedef long long ll;
const double eps = 1e-8;
const int maxn = 100000 + 100;
char latter[maxn], former[maxn];
int Next[maxn];
void GETnext()      //有优化
{
int i, j, k;
int L = strlen(former);
Next[0] = -1;
i = 0;
j = -1;
while (i < L && j < L)
{
if (j == -1 || former[i] == former[j])
{
i++;
j++;
//优化
if (former[i] == former[j])
Next[i] = Next[j];
else
Next[i] = j;
//如果不要优化,这样:
//Next[i] = j;
}
else
j = Next[j];
}
}
int KMP()       //返回目标串在主串中出现的次数
{
int i, j;
GETnext();
int L1 = strlen(former);
int L2 = strlen(latter);
i = 0;
j = 0;
int res = 0;
while (i < L2)
{
if (j == -1 || latter[i] == former[j])
{
if (j == L1 - 1)
{
return 1;
}
i++;
j++;
}
else
j = Next[j];
}
return 0;
}
int main()
{
int i, j, k, u, n, m;
while (scanf("%d", &n) != EOF)
{
for (m = 1; m <= n; m++)
{
scanf("%s %s", latter, former);
int L1 = strlen(latter);
int L2 = strlen(former);
if (L2 == 1 && former[0] == '0')
{
printf("Alice\n");
continue;
}
if (L1 < L2)
{
printf("Bob\n");
}
else
{
if (KMP())
{
printf("Alice\n");
}
else
{
reverse(latter, latter+L1);
if (KMP())
{
printf("Alice\n");
}
else
{
printf("Bob\n");
}
}
}
}
}
return 0;
}

T11 错位排列+逆元

#include <cstdio>
#include <cstring>
#include <cmath>
#include <queue>
#include <algorithm>
#include <cctype>
#include <vector>
#include <map>
#include <set>
using namespace std;
typedef long long ll;
const double eps = 1e-8;
const int maxn = 100000 + 100;
const int MOD = 1e9 + 7;
int N, K;
ll cuo[10010];
ll C[10010];
void quancuo()
{
int i, j;
cuo[0] = 1;
cuo[1] = 0;
cuo[2] = 1;
for (i = 3; i <= 10000; i++)
{
cuo[i] = ((cuo[i - 1] + cuo[i - 2]) % MOD) * (i - 1) % MOD;
}
}
ll Extend_Euclid(ll a, ll b, ll&x, ll& y)
{
if (b == 0)
{
x = 1, y = 0;
return a;
}
ll d = Extend_Euclid(b, a%b, x, y);
ll t = x;
x = y;
y = t - a / b*y;
return d;
}


//a在模n乘法下的逆元,没有则返回-1
ll inv(ll a, ll n)
{
ll x, y;
ll t = Extend_Euclid(a, n, x, y);
if (t != 1)
return -1;
return (x%n + n) % n;
}
void getC(ll n)
{
ll i, j, k;
C[0] = 1;
C[1] = n;
for (i = 2; i <= n; i++)
{
C[i] = C[i - 1] * (n - i + 1) % MOD * inv(i, MOD) % MOD;
}
//for (i = 0; i <= n; i++)
// printf("%lld\n", C[i]);
//for (i = 1; i <= n+1; i++)
//{
// for (j = 1; j <=i; j++)
// {
// printf("%lld ", C[i][j]);
// }
// putchar('\n');
//}
}
int main()
{
int i, j, k, u, n, m, a, b;
quancuo();
while (scanf("%d", &n) != EOF)
{
for (m = 1; m <= n; m++)
{
scanf("%d %d", &N, &K);
ll res = 0;
getC((ll)N);
for (i = K; i <= N; i++)
{
res = (res + C[i] * cuo[N - i] % MOD) % MOD;
}
printf("%lld\n", res);
}
}
return 0;
}


T12  模拟+博弈论

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <stack>
#include <string>
using namespace std;


#define MAXN 110
char map[4][4];
bool found=0;
char self,oppoent;
void init()
{


found=0;
     //1self 0 oppoent 2 empty
}
bool judgewin()
{
for(int i=0;i<3;++i)
{
bool legal=1;
for(int j=0;j<3 && legal;++j)
{
if(map[i][j]!=self)
legal=0;
}
if(legal)
return 1;
}
for (int i = 0; i < 3 ; ++i)
{
bool legal=1;
for(int j=0;j<3 && legal;++j)
{
if(map[j][i]!=self)
legal=0;
}
if(legal)
return 1;
}
bool legal=1;
for (int i = 0; i < 3; ++i)
{
if(map[i][i]!=self)
legal=0;
}
if(legal)
return 1;
legal=1;
for (int i = 0; i < 3; ++i)
{
if(map[2-i][i]!=self)
legal=0;
}
if(legal)
return 1;
return 0;
}
bool judgenextwin()
{
bool winpoint[3][3];
int nw=0;
for(int i=0;i<3;++i)
for(int j=0;j<3;++j)
winpoint[i][j]=0;
for(int i=0;i<3;++i)
{
int empty=0;
int mypoint=0;
int ex,ey;
for(int j=0;j<3;++j)
{
if(map[i][j]==self)
mypoint++;
if(map[i][j]=='.')
{
empty++;
ex=i; ey=j;
}
}
if( empty==1 && mypoint==2 &&!winpoint[ex][ey])
{
winpoint[ex][ey]=1;
nw++;
}
}
for(int i=0;i<3;++i)
{
int empty=0;
int mypoint=0;
int ex,ey;
for(int j=0;j<3;++j)
{
if(map[j][i]==self)
mypoint++;
if(map[j][i]=='.')
{
empty++;
ex=i; ey=j;
}
}
if( empty==1 && mypoint==2 &&!winpoint[ex][ey])
{
winpoint[ex][ey]=1;
nw++;
}
}
int empty=0;
int mypoint=0;
int ex,ey;
for (int i = 0; i < 3; ++i)
{
if(map[i][i]==self)
mypoint++;
if(map[i][i]=='.')
{
empty++;
ex=i; ey=i;
}
}
if( empty==1 && mypoint==2 &&!winpoint[ex][ey])
{
winpoint[ex][ey]=1;
nw++;
}


empty=0;
mypoint=0;
for (int i = 0; i < 3; ++i)
{
if(map[2-i][i]==self)
mypoint++;
if(map[2-i][i]=='.')
{
empty++;
ex=2-i; ey=i;
}
}
if( empty==1 && mypoint==2 &&!winpoint[ex][ey])
{
winpoint[ex][ey]=1;
nw++;
}
if(nw>=2)
return 1;
else return 0;
}
void walk1()
{
for (int i = 0; i < 3 && !found; ++i)
{
for(int j=0;j<3 && !found;++j)
{
if(map[i][j]!='.') continue;
map[i][j]=self;
if(judgewin() || judgenextwin())
found=1;
map[i][j]='.';
}
}
}
int main(int argc, char const *argv[])
{
//freopen("input.txt","r",stdin);
    int t;
    while(cin >> t)
    {while(t--)
    {
    init();
for(int i=0;i<3;++i)
for(int j=0;j<3;++j)
{
getchar();
scanf("%c",&map[i][j]);
}
getchar();
scanf("%c",&self);
if('x'!=self)
oppoent='x';
else oppoent='o';
walk1();
if(found)
printf("Kim win!\n" );
else printf("Cannot win!\n");
    }}
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值