# 全程NOIP计划 模拟赛1

## 说在前面

（捆绑测试\fn）
yzhang和dead_X差点ak，orz。

## A 平面几何

# include <bits/stdc++.h>
using namespace std;
# define int long long
const int N = 5e4 + 5;
int n;
int ax[N],ay[N],bx[N],by[N],Qu[N];
struct Fenshu
{
int p,q; // p / q
Fenshu() {}
Fenshu(int _p,int _q) : p(_p),q(_q) {}
};

pair<Fenshu,Fenshu> Intersect(int i, int j) {
long long px = (long long)(ay[j] * bx[j] - ax[j] * by[j]) * (ax[i] - bx[i]) - (long long)(ay[i] * bx[i] - ax[i] * by[i]) * (ax[j] - bx[j]);
long long py = (long long)(ax[i] * by[i] - ay[i] * bx[i]) * (ay[j] - by[j]) - (long long)(ax[j] * by[j] - ay[j] * bx[j]) * (ay[i] - by[i]);
int q = (ax[i] - bx[i]) * (ay[j] - by[j]) - (ax[j] - bx[j]) * (ay[i] - by[i]);
if (q < 0) px *= -1, py *= -1, q *= -1;
return make_pair(Fenshu(px,q),Fenshu(py,q));
}

bool operator > (const struct Fenshu &x,const struct Fenshu &y)
{
if(1ll * x.p * 1ll * y.q > 1ll * x.q * 1ll * y.p) return 1;
else return 0;
}
bool operator < (const struct Fenshu &x,const struct Fenshu &y)
{
if(1ll * x.p * 1ll * y.q < 1ll * x.q * 1ll * y.p) return 1;
else return 0;
}
bool compare(int i,int j)
{
return Fenshu(bx[i] - ax[i],by[i] - ay[i]) < Fenshu(bx[j] - ax[j],by[j] - ay[j]);
}
signed main(void)
{
scanf("%lld",&n);
for(int i = 1; i <= n; i++)
{
scanf("%lld%lld%lld%lld",&ax[i],&ay[i],&bx[i],&by[i]);Qu[i] = i;
if(by[i] < ay[i]) swap(by[i],ay[i]),swap(bx[i],ax[i]);
}
sort(Qu + 1,Qu + n + 1,compare);
struct Fenshu ans = Fenshu(-1e9-7,1);
for(int i = 1; i < n; i++)
{
if(Intersect(Qu[i],Qu[i + 1]).second > ans) ans = Intersect(Qu[i],Qu[i + 1]).second;
}
// printf("%lld %lld\n",ans.p,ans.q);
printf("%lf\n",double(ans.p) / double(ans.q));
return 0;
}

## B. 有向图

$$m$$为偶数一定有解。考虑求出它的一个dfs树，然后将不在dfs树上的随意乱定边，自底向上，根据子树情况判断是否向父亲节点连边。

# include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
int n,m;
vector <int> g[N];
bool vis[N];
int dep[N],cnt[N];
void dfs(int x,int fa)
{
dep[x] = dep[fa] + 1;
vis[x] = 1;
for(int i = 0; i < (int)g[x].size(); i++)
{
int v = g[x][i];
if(v == fa) continue;
if(vis[v])
{
if(dep[v] < dep[x])
{
cnt[x] ^= 1;
printf("%d %d\n",x,v);
}
}
else dfs(v,x);
}
if(!fa) return;
if(cnt[x]) printf("%d %d\n",x,fa);
else cnt[fa] ^= 1,printf("%d %d\n",fa,x);
return;
}
int main(void)
{
scanf("%d%d",&n,&m);
if(m & 1) printf("-1\n");
else
{
for(int i = 1; i <= m; i++)
{
int u,v; scanf("%d%d",&u,&v);
g[u].push_back(v),g[v].push_back(u);
}
dfs(1,0);
}
return 0;
}

（考场上写了除无特殊情况外的75pts，结果被捆绑测试搞挂了一堆）

## C 数学题

$$dp[i][j]$$为考虑了前$$i$$个数，且共选了$$j$$个数的总和。

$dp[i][j] = \left( \sum_{c = 0}^j dp[i - 1][j - c] \right) \cdot a_i^c$

# include <bits/stdc++.h>
using namespace std;
# define int long long
const int N = 1e5 + 5,K = 305;
const int mod = 998244353;
typedef long long ll;
int dp[K],f[K],n,k;
ll qmulti(int x,int p)
{
int ans = 1;
while(p)
{
if(p & 1) ans = ans = (ll)x * ans % mod;
x = (ll) x * x % mod;
p >>= 1;
}
return ans % mod;
}
signed main(void)
{
scanf("%lld%lld",&n,&k);
dp[0] = f[0] = 1;
for(int i = 1; i <= n; i++)
{
int x; scanf("%lld",&x);
for(int j = 1; j <= k; j++)
{
dp[j] = (dp[j] + dp[j - 1] * x * 1ll) % mod;
f[j] = (f[j] + f[j - 1] * 1ll) % mod;
}
}
printf("%lld\n",(ll)dp[k] * qmulti(f[k],mod - 2) % mod);
return 0;
}

## D 俄罗斯方块

# include <bits/stdc++.h>
using namespace std;
const int mod = 1e9 + 7;
long long n;
struct Matrix
{
int a[5][5];
}M;
Matrix operator * (const struct Matrix &x,const struct Matrix &y)
{
Matrix ans;
for(int i = 1; i <= 4; i++) for(int j = 1; j <= 4; j++) ans.a[i][j] = 0;
for(int i = 1; i <= 4; i++)
{
for(int j = 1; j <= 4; j++)
{
for(int k = 1; k <= 4; k++)
ans.a[i][j] = (ans.a[i][j] + (long long)x.a[i][k] * (long long)y.a[k][j]) % mod;
}
}
return ans;
}
Matrix qPOW(Matrix x,long long p)
{
Matrix ans;
for(int i = 1; i <= 4; i++) for(int j = 1; j <= 4; j++) ans.a[i][j] = (i == j) ? 1 : 0;
while(p)
{
if(p & 1) ans = ans * x;
x = x * x,p >>= 1;
}
return ans;
}
int main(void)
{
int T; scanf("%d",&T);
M.a[1][1] = 1,M.a[1][2] = 2,M.a[1][3] = 0,M.a[1][4] = 2;
M.a[2][1] = 1,M.a[2][2] = 3,M.a[2][3] = 2,M.a[2][4] = 2;
M.a[3][1] = 3,M.a[3][2] = 8,M.a[3][3] = 5,M.a[3][4] = 6;
M.a[4][1] = 1,M.a[4][2] = 2,M.a[4][3] = 1,M.a[4][4] = 2;
while(T--)
{
scanf("%lld",&n);
struct Matrix ANS = qPOW(M,n / 5);
printf("%d\n",(ANS.a[1][1] + ANS.a[1][2] + 3ll * ANS.a[1][3] + ANS.a[1][4]) % mod);
}
return 0;
}
posted @ 2021-07-26 11:24  luyiming123  阅读(63)  评论(0编辑  收藏  举报