B
建图!?
真没想到这个,图论见识的还是少
全源最短路
有时间再看看
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 300 + 5;
int a[N][N];
int d[N][N];
int main() {
int n;
cin >> n;
memset(d, 63, sizeof d);
for(int i = 0; i < n; ++ i)
for(int j = 0; j < n; ++ j)
cin >> a[i][j];
for(int i = 0; i < n; ++ i)
for(int j = 0, k = 0;j < n; ++ j)
if(a[i][j])
d[i][j] = k++;
for(int k = 0; k < n; ++ k)
for(int i = 0; i < n; ++ i)
for(int j = 0; j < n; ++ j)
d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
int ans = d[0][n-1] < 1 << 25 ? d[0][n-1] : -1;
cout << ans << endl;
}
G
这码风真是一言难尽,有时间再补了,先把答案贴上
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 1e6 + 5;
const int mod = 1e9 + 7;
int fac[N], ifac[N];
int T[20];
typedef long long LL;
int pow(int a, int b) {
LL res = 1;
for(;b;b >>= 1, a = (LL) a * a % mod)
if (b & 1)
res = res * a % mod;
return res;
}
int main()
{
int Max = 1000000;
fac[0] = 1;
for(int i = 1; i <= Max; ++ i) fac[i] = (LL)fac[i - 1] * i % mod;
ifac[Max] = pow(fac[Max], mod - 2);
for(int i = Max-1; i >= 0; -- i) ifac[i] = (LL)ifac[i + 1] * (i + 1) % mod;
LL Sum = 0;
int Count = 0;
for(int i = 1; i <= 9; ++ i) {
int temp;
cin >> temp;
T[i] = temp;
Sum += i * temp;
Count += T[i];
}
Sum %= mod;
LL part_I = 0;
for(int i = 1; i <= Count; ++ i) part_I = (part_I * 10 + 1) % mod;
LL part_mul = fac[Count - 1];
LL part_div = 1;
for(int i = 1; i<= 9; ++ i) part_div = part_div * ifac[T[i]] % mod;
// cout << Sum << ' ' << part_I << ' ' << part_mul << ' ' << part_div << endl;
cout << (LL)Sum * part_I %mod * part_mul %mod * part_div % mod << endl;
return 0;
}
J题
是道比较难的dp,有时间再研究
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iostream>
#define ll long long
using namespace std;
ll f[2001][2001][3];
ll ch[2001],vi[2001],ans;
ll pre[2001],n;
ll read(){
ll x=0,w=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
return x*w;
}
ll cal(ll l,ll r){
return pre[l]+pre[n]-pre[r-1];
}
int main(){
//freopen("10.in","r",stdin);
//freopen("10.out","w",stdout);
n=read();
for(ll i=1;i<=n;i++)ch[i]=read(),ans+=ch[i];
for(ll i=1;i<=n;i++)vi[i]=read();
memset(f,63,sizeof(f));
// cout<<ans<<endl;
for(ll i=1;i<=n;i++)f[i][i][0]=f[i][i][1]=0;
for(ll i=1;i<=n;i++)pre[i]=pre[i-1]+vi[i];
for(ll len=1;len<=n;len++){
for(ll i=1;i<=n-len+1;i++){
ll j=i+len-1;
f[i][j][0]=min(f[i][j][0],f[i+1][j][0]+cal(i,j+1));//已经合并i+1,j,当前在i+1,准备向左到i
f[i][j][0]=min(f[i][j][0],f[i+1][j][1]+(j-i)*cal(i,j+1));//已经合并i+1,j,当前在j,准备向左到i
f[i][j][1]=min(f[i][j][1],f[i][j-1][0]+(j-i)*cal(i-1,j));//已经合并i,j-1,当前在i,准备向右到j
f[i][j][1]=min(f[i][j][1],f[i][j-1][1]+cal(i-1,j));//已经合并i,j-1,当前在j-1,准备向右到j
//cout<<"f["<<i<<"]["<<j<<"]"<<" left="<<f[i][j][0]<<' '<<" right="<<f[i][j][1]<<endl;
}
}
/* for(ll i=1;i<=n;i++)
for(ll j=1;j<=n;j++){
// cout<<"f["<<i<<"]["<<j<<"]"<<" left="<<f[i][j][0]<<' '<<" right="<<f[i][j][1]<<endl;
}*/
// cout<<ans<<' '<<min(f[1][n][1],f[1][n][0])<<endl;
printf("%lld\n",ans-min(f[1][n][1],f[1][n][0]));
return 0;
}
F题
小思维,题目数据有点怪,int居然不wa,而且这个开 ans 开 ll 就wa就离谱
#include<iostream>
using namespace std;
const int N = 200010;
typedef long long ll;
int n, m;
int ans[200010], sum, op, l, r, z;
int main()
{
ios::sync_with_stdio(false);
cin >> n >> m;
while(m --)
{
cin >> op;
if(op == 1)
{
cin >> l;
cout << sum - ans[l] << endl;
}
else
{
cin >> l >> r >> z;
for(int i = l;i <= r; ++i)
ans[i] += (r - l + 1) * z;
sum += (r - l + 1) * z;
}
}
return 0;
}
C题
最小生成树
遇到必须添加的边的端点时, 就把这条必须加的边加进去
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N = 1e6 + 9;
ll n, m;
ll t;
ll f[N];
long long ans = 0;
struct node
{
ll x, y, z;
}e[N];
bool cmp(node a, node b)
{
return a.z < b.z;
}
/*ll find(ll x)
{
return f[x] == x ? x : f[x] = find(f[x]);
}*/
ll find(ll x)
{
ll r = x, j, k = x;
while(r != f[r]) r = f[r]; // 寻找根节点
while(k != r)
{
j = f[k]; // 暂存此时k的父节点
f[k] = r; // 将k的父节点改为根节点
k = j; // k移到父节点 直至全改为根节点
}
return r;
}
int main()
{
cin >> n >> m;
for(int i = 1; i <= m; ++i)
{
scanf("%lld%lld%lld", &e[i].x,&e[i].y,&e[i].z);
}
if(n == 1){
cout << 0;return 0;
}
cin >> t;
for(ll i = 0; i <= n; ++i) f[i] = i;
ll x1 = e[t].x, x2 = e[t].y, x3 = e[t].z;
sort(e+1,e+1+m,cmp);
for(ll i = 1; i <= m; ++i)
{
if(e[i].x == x1 && e[i].y == x2 && e[i].z == x3) {
t = i;break;
}
}
//cout << endl << t << endl;
//f[e[t].x] = e[1].x;
//f[e[t].y] = e[1].x;
//ans += e[t].z;
//cout << ans << endl;
//if()
bool q = 1;
for(int i = 1; i <= m; ++i)
{
ll x = find(e[i].x);
ll y = find(e[i].y);
if(x == y) continue;
//cout << e[i].x << " " << e[i].y << " " << e[i].z << endl;
if((e[i].x == e[t].x || e[i].x == e[t].y || e[i].y == e[t].x || e[i].y == e[t].y) && q)
{
//cout << " \n";
ans += e[t].z;
f[find(e[t].x)] = x;
f[find(e[t].y)] = x;
q=0;
if(e[i].x == e[t].x && e[i].y == e[t].y){
continue;
}
}
f[y] = x;
ans += e[i].z;
//cout << ans << endl;
}
cout << ans << endl;
return 0;
}
/*
4 4
1 2 3
2 3 4
2 4 3
3 4 3
2
*/