天天快乐编程2020年OI集训队 训练9题解

1.4839: 麦森数

NOIP2003普及组T1
2p与2p-1有着相同的位数,2的p次方末位一定不为0，减1位数不会改变，那我们可以直接求2^p的位数，位数为log10(2*p)+1

#include<bits/stdc++.h>
using namespace std;
int a[510]={2};
#define M 500
void mul()
{
for(int i=0;i<M;i++)
a[i]*=2;
for(int i=0;i<M;i++)
a[i+1]+=a[i]/10,a[i]%=10;
}
void square()
{
int b[510]={0};
for(int i=0;i<M;i++)
for(int j=0;j<M;j++)
if(i+j<M)
b[i+j]+=a[i]*a[j];
for(int i=0;i<M;i++)
b[i+1]+=b[i]/10,b[i]%=10;
for(int i=0;i<M;i++)
a[i]=b[i];

}
void quickmi(int x)
{
if(x/2>1) quickmi(x/2);
square();
if(x%2) mul();
}
int main()
{
int p;
scanf("%d",&p);
printf("%d\n",(int)(log10(2.0)*p)+1);
quickmi(p);
a[0]--;
for(int i=M-1;i>=0;i--)
printf("%d",a[i]);
}


2.6020: 扫雷游戏

NOIP2015 普及组T2

#include<bits/stdc++.h>
using namespace std;
//有雷为1，无雷为0
bool a[105][105];
int main()
{
int n,m;
char tmp;
cin>>n>>m;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
cin>>tmp;
//如果是地雷就将这个点设为1
if(tmp=='*') a[i][j]=1;
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(a[i][j]==1)
{
printf("*"); //如果是地雷不用输出数字
}
else
{
printf("%d",a[i+1][j+1]+a[i+1][j-1]+a[i+1][j]+a[i][j+1]+a[i][j-1]+a[i-1][j+1]+a[i-1][j]+a[i-1][j-1]);
}
}
printf("\n");
}
return 0;
}


3.6272: 龙虎斗

NOIP2018 普及组T2

#include <bits/stdc++.h>
using namespace std;
long long a[100005], s1, s2, sum2, sum1, minn;
int m, n, p1, ans;
int main()
{
cin >> n;
for (int i = 1; i <= n; i++)
cin >> a[i];
cin >> m >> p1 >> s1 >> s2;
a[p1] += s1;
for (int i = 1; i < m; i++)
sum1 += a[i] * (m - i);
for (int i = m + 1; i <= n; i++)
sum2 += a[i] * (i - m);
minn = abs(sum1 - sum2);
ans = m;
for (int i = 1; i < m; i++)
if (abs(sum1 + s2 * (m - i) - sum2) < minn)
{
minn = abs(sum1 + s2 * (m - i) - sum2);
ans = i;
}
for (int i = m + 1; i <= n; i++)
if (abs(sum2 + s2 * (i - m) - sum1) < minn)
{
minn = abs(sum2 + s2 * (i - m) - sum1);
ans = i;
}
cout << ans;
}


4.4866: 瑞士轮

NOIP2011普及组T3

#include <bits/stdc++.h>
using namespace std;
const int N = 200005;
struct point
{
int num, id, w;
bool operator<(const point &tmp) const
{
if (num != tmp.num)
return num > tmp.num;
return id < tmp.id;
}
} a[N >> 1], b[N >> 1], tmp[N];
int n, r, q;
void merge()
{
int i = 1, j = 1, k = 1;
while (i <= n && j <= n)
{
if (a[i].num > b[j].num || a[i].num == b[j].num && a[i].id < b[j].id)
tmp[k++] = a[i++];
else
tmp[k++] = b[j++];
}
while (i <= n)
tmp[k++] = a[i++];
while (j <= n)
tmp[k++] = b[j++];
}
int main()
{
scanf("%d%d%d", &n, &r, &q);
for (int i = 1; i <= 2 * n; i++)
scanf("%d", &tmp[i].num), tmp[i].id = i;
for (int i = 1; i <= 2 * n; i++)
scanf("%d", &tmp[i].w);
sort(tmp + 1, tmp + 2 * n + 1);
for (int t = 1; t <= r; t++)
{
int cnt = 1;
for (int i = 1; i < 2 * n; i += 2)
{
if (tmp[i].w > tmp[i + 1].w)
a[cnt] = tmp[i], b[cnt] = tmp[i + 1], a[cnt++].num++;
else
a[cnt] = tmp[i + 1], b[cnt] = tmp[i], a[cnt++].num++;
}
merge();
}
printf("%d\n", tmp[q].id);
return 0;
}


5.5914: 铺设道路

NOIP2018提高组Day1T1

#include <bits/stdc++.h>
using namespace std;
int a[100001];

int main()
{
int n;
cin >> n;
for (int i = 1; i <= n; ++i)
{
scanf("%d", &a[i]);
}
int sum = 0;
for (int i = 1; i <= n; ++i)
{
if (a[i] > a[i - 1])
{
sum += a[i] - a[i - 1];
}
}
printf("%d\n", sum);
}


6.4811: 最优贸易

NOIP2009提高组T2

#include <bits/stdc++.h>
using namespace std;
const int M = 500010;
const int N = 100010;
int dist1[N], dist2[N], vis1[N], vis2[N];
vector<int> e1[N], e2[N];
struct pt1
{
int u, dis;
bool operator>(const pt1 &t) const { return dis > t.dis; }
} p1[N];
struct pt2
{
int u, dis;
bool operator<(const pt2 &t) const { return dis < t.dis; }
} p2[N];
priority_queue<pt1, vector<pt1>, greater<pt1>> q1;
priority_queue<pt2, vector<pt2>, less<pt2>> q2;
int n, m, money[N];
void dj1()
{
for (int i = 1; i <= n; i++)
{
dist1[i] = money[i];
}
q1.push((pt1){1, dist1[1]});
while (!q1.empty())
{
int u = q1.top().u;
q1.pop();
if (vis1[u])
continue;
vis1[u] = 1;
for (int i = 0; i < e1[u].size(); i++)
{
int v = e1[u][i];
if (dist1[v] > dist1[u])
{
dist1[v] = dist1[u];
q1.push((pt1){v, dist1[v]});
}
if (vis1[v] == 0)
q1.push((pt1){v, dist1[v]});
}
}
}
void dj2()
{
for (int i = 1; i <= n; i++)
dist2[i] = money[i];
q2.push((pt2){n, dist2[n]});
while (!q2.empty())
{
int u = q2.top().u;
q2.pop();
if (vis2[u])
continue;
vis2[u] = 1;
for (int i = 0; i < e2[u].size(); i++)
{
int v = e2[u][i];
if (dist2[v] < dist2[u])
{
dist2[v] = dist2[u];
q2.push((pt2){v, dist2[v]});
}
if (vis2[v] == 0)
q2.push((pt2){v, dist2[v]});
}
}
}
int main()
{
cin >> n >> m;
for (int i = 1; i <= n; i++)
cin >> money[i];
for (int i = 1; i <= m; i++)
{
cin >> u >> v >> op;
if (op == 1)
e1[u].push_back(v), e2[v].push_back(u);
else
{
e1[u].push_back(v);
e2[v].push_back(u);
e1[v].push_back(v);
e2[u].push_back(v);
}
}
dj1();
dj2();
int ans = 0;
for (int i = 1; i <= n; i++)
{
if (vis1[i] && vis2[i])
ans = max(ans, dist2[i] - dist1[i]);
}
printf("%d", ans);
return 0;
}


7.4804: 树网的核

NOIP2007提高组T4

1、 通过Floyd算法求出顶点对之间的最短路径，并记录下具体的最短路径。
2、 标记所有在直径上的点。
3、 枚举路径的起点，进行DFS穷举路径的终点。
4、 对于一条确定下来的路径，通过直接模拟的方法得出偏心矩。

#include<bits/stdc++.h>
using namespace std;

const int maxn=305;
int G[maxn][maxn];
int main()
{
int n,s;
scanf("%d%d",&n,&s);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(i==j)G[i][j]=0;
else G[i][j]=0x3f3f3f3f;
for(int i=1,u,v,w;i<n;i++)
{
scanf("%d%d%d",&u,&v,&w);
G[u][v]=G[v][u]=min(G[u][v],w);
}
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
G[i][j]=min(G[i][j],G[i][k]+G[k][j]);
int ans=1e9;
for(int i=1;i<=n;i++)
for(int j=i;j<=n;j++)
{
if(G[i][j]>s)continue;
int maxx=0;
for(int k=1;k<=n;k++)
maxx=max(maxx,(G[i][k]+G[j][k]-G[i][j])/2);
ans=min(ans,maxx);
}
printf("%d\n",ans);
return 0;
}

posted @ 2020-10-17 10:04  暴力都不会的蒟蒻  阅读(133)  评论(0编辑  收藏  举报