A切蛋糕的贝贝
题目链接
关键点:
1、题目已经定下来了切的块数,即六块,且比例为1:1:4:5:1:4,那么只有刚刚好为题目要求的比例的倍数,才可以切。1+1+4+5+1+4 = 16,即为16的倍数的边形才可以满足要求,其他一律不行,
2、且一共切成6块,根据题目要求的切法,最少也要切5次
# include <bits/stdc++.h>
using namespace std;
int n;
int main()
{
cin>>n;
if (n%16 == 0)
{
cout<<"5"<<endl;
}
else
cout<<"-1"<<endl;
return 0;
}
B抱歉,这没有集美
题目链接
关键点:
1、可以发现要是序列的排序和其所分配的号至少要出现一个公倍数为偶数,那么至少要有一个偶数在偶数位,直接这样求很麻烦,反过来我们可以求所有的奇数在偶数位的情况数,然后将总数的全排列个数减去该数即可
2、又可以发现,设人数为n,则奇数在偶数位的情况数为n的全排列 - ((n+1)*n/2)的全排列
即nd的全排列 - (奇数个数在偶数位上的排列和*((n - 偶数位)的全排列))
比方说人数为5,则奇数个数为3,偶数位为2,5的全排列 - A(上2下3)*A(上3下3)
不会打数学符号。。。
完整代码:
# include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll MOD = 1e9+7;
ll sum1 = 1, sum2 = 1, num;
int n;
int ji, ou;
int main()
{
cin>>n;
for (int i=1; i<=n; i++)
sum1 = sum1*i%MOD;
for (int i=1; i<=(n+1)/2; i++)
sum2 = sum2*i%MOD;
sum2 = sum2*sum2%MOD;
num = (sum1-sum2+MOD)%MOD;
cout<<num<<endl;
return 0;
}
D点分治分点
题目链接
关键点:
1、首先要理解题目中有关简单路径的定义:即从起点到终点的所有路径长度的最小值
d(u,v) = max(u->v的最短路径);
2、那么我们可以将简单路径作为路径长度,来求最长的d
3、题目中说明了可能存在的重边和自环,那么就用迪杰斯特拉算法,求最长路径
4、将最小堆改为利用最大堆,并且有关路径更新的要求也不同,可以发现,求出两点的d值,后序再次经过时,其d值也会受先前的d值影响,那么就可以用来更新
定义low[x],为起点到x的最小路径长度
min(low[tmp.x], edge[i].len)>d[y]
满足要求,就更新low值和d值
完整代码:
# include <bits/stdc++.h>
using namespace std;
typedef long long ll;
struct ty1{
ll t, len, next;
}edge[100000+10];
struct ty2{
ll x, low;
bool operator < (const ty2& a)const{
return low<a.low;
}
};
priority_queue<ty2>q;
ll d[100000+10], vis[100000+10], head[100000+10], low[100000+10];
int n, m, s, cnt;
void addedge(int x, int y, int len)
{
edge[++cnt].t = y;
edge[cnt].len = len;
edge[cnt].next = head[x];
head[x] = cnt;
}
void dij()
{
memset(d, -1, sizeof(d));
memset(vis, 0, sizeof(vis));
ty2 tmp;
tmp.low = 1000000000+10, tmp.x = s;
low[s] = 1000000000+10;
q.push(tmp);
while (!q.empty())
{
ty2 tmp = q.top();
q.pop();
if (vis[tmp.x]) continue;
vis[tmp.x] = 1;
for (int i=head[tmp.x]; i!=-1; i=edge[i].next)
{
int y = edge[i].t;
// cout<<edge[i].len<<endl;
if (min(low[tmp.x], edge[i].len)>d[y])
{
// cout<<"123"<<endl;
d[y] = min(low[tmp.x], edge[i].len);
low[y] = d[y];
ty2 tmp;
tmp.x = y, tmp.low = d[y];
q.push(tmp);
}
}
}
}
int main()
{
cin>>n>>m>>s;
memset(head, -1, sizeof(head));
for (int i=1; i<=m; i++)
{
int x, y, len;
cin>>x>>y>>len;
addedge(x, y, len);
}
dij();
for (int i=1; i<=n; i++)
{
if (i == s)
cout<<"-1 ";
else
cout<<d[i]<<" ";
}
return 0;
}