1:24 做出 D, 这场打的还行,主要是最近手感不错。
A - Fence
直接取上界-1即可:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define re register
#define ls (o<<1)
#define rs (o<<1|1)
//#define m (l+r)/2
#define pb push_back
const double PI= acos(-1.0);
const int M = 1e5+7;
/*
int head[M],cnt=1;
void init(int n){cnt=1;for(int i=0;i<=n;i++)head[i]=0;}
struct EDGE{int to,nxt,w;}ee[M*2];
void add(int x,int y,int w){ee[++cnt].nxt=head[x],ee[cnt].w=w,ee[cnt].to=y,head[x]=cnt;}
*/
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int T;
cin>>T;
while(T--){
ll a,b,c;
cin>>a>>b>>c;
ll d=a+b+c;
cout<<d-1<<endl;
}
return 0;
}
B - Nice Matrix
容易发现,相互影响的位置最多4个,即四角。
相当于移动最小次数,让4个数相同。显然移动到中位数是最优解。
注意奇数行与奇数列的特判。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define re register
#define ls (o<<1)
#define rs (o<<1|1)
//#define m (l+r)/2
#define pb push_back
const double PI= acos(-1.0);
const int M = 1e5+7;
/*
int head[M],cnt=1;
void init(int n){cnt=1;for(int i=0;i<=n;i++)head[i]=0;}
struct EDGE{int to,nxt,w;}ee[M*2];
void add(int x,int y,int w){ee[++cnt].nxt=head[x],ee[cnt].w=w,ee[cnt].to=y,head[x]=cnt;}
*/
ll a[110][110];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int T;
cin>>T;
while(T--){
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++){
cin>>a[i][j];
}
ll ans=0;
//1 3 4 6
for(int i=1;i<=n/2;i++)
for(int j=1;j<=m/2;j++){
ll b[5];
b[1]=a[i][j];
b[2]=a[n-i+1][j];
b[3]=a[i][m-j+1];
b[4]=a[n-i+1][m-j+1];
// cout<<b[1]<<" "<<b[2]<<" "<<b[3]<<" "<<b[4]<<endl;
sort(b+1,b+1+4);
// cout<<" == "<<b[1]<<" "<<b[2]<<" "<<b[3]<<" "<<b[4]<<endl;
ll tp=min(abs(b[2]-b[1])+abs(b[2]-b[3])+abs(b[2]-b[4]),
abs(b[3]-b[1])+abs(b[3]-b[2])+abs(b[3]-b[4]));
ans+=tp;
}
if(n&1){
int id=(n+1)/2;
for(int j=1;j<=m/2;j++)ans+=abs(a[id][j]-a[id][m-j+1]);
}
if(m&1){
int id=(m+1)/2;
for(int i=1;i<=n/2;i++)ans+=abs(a[i][id]-a[n-i+1][id]);
}
cout<<ans<<endl;
}
return 0;
}
C - Bargain
经典算贡献的题目。
只能删除子串(即连续位置的数字)。
最后肯定是一段数字 中间扣去一段,然后左右两端数字拼一起是最终结果。
我们枚举右端id。然后右端数字就知道了,左端就枚举左端断开的位置,然后把左端位置的数*(10^右端数字个数)
即可。
这里枚举复杂度总共On^2,所以预处理出前i位数字组成数的数值即可。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define re register
#define ls (o<<1)
#define rs (o<<1|1)
//#define m (l+r)/2
#define pb push_back
const double PI= acos(-1.0);
const int M = 1e5+7;
/*
int head[M],cnt=1;
void init(int n){cnt=1;for(int i=0;i<=n;i++)head[i]=0;}
struct EDGE{int to,nxt,w;}ee[M*2];
void add(int x,int y,int w){ee[++cnt].nxt=head[x],ee[cnt].w=w,ee[cnt].to=y,head[x]=cnt;}
*/
char s[M];
const int mod = 1e9+7;
ll qpow(ll a,ll b){
ll ans=1;
while(b){
if(b&1)ans=ans*a%mod;
a=a*a%mod;
b/=2;
}
return ans;
}
ll sm[M];
ll ssm[M];
int a[M];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin>>(s+1);
int n=strlen(s+1);
for(int i=1;i<=n;i++)
a[i]=s[i]-'0',
sm[i]=(sm[i-1]*10%mod + a[i])%mod,
ssm[i]=(ssm[i-1] + sm[i])%mod;
ll ans=0,tp=1,st=0;
for(int i=n;i>=1;i--){
ans+=ssm[i-1]*tp%mod;
ans+=st*i%mod;
// cout<<ssm[i-1]<<" "<<ssm[i-1]*tp<<" "<<st<<" "<<st*i<<endl;
ans%=mod;
tp=tp*10%mod;
st=(st+a[i]*qpow(10,n-i)%mod)%mod;
}
cout<<ans<<endl;
return 0;
}
D - Returning Home
显然有2种走法:
第一种:不适用传送点,直接从起点走到终点。
第二种:从起点走到一个传送点,然后经过若干次传送点之间的转换,最后从最后一个传送点走到终点。
显然是单源最短路,dij即可。
但是我们发现如果直接连边会有n^2 条。
但其实仔细分析可知:每个传送点走向另一个传送点时,一定先经过x轴方向最近的两个传送点,或者y轴最近的2个传送点,然后再由他们到达更远的传送点。
也就是说每个点只需要连至多4条出边即可。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define re register
#define ls (o<<1)
#define rs (o<<1|1)
//#define m (l+r)/2
typedef pair<ll,int> pli;
#define pb push_back
const double PI= acos(-1.0);
const int M = 4e5+7;
int head[M],cnt=1;
void init(int n){cnt=1;for(int i=0;i<=n;i++)head[i]=0;}
struct EDGE{int to,nxt,w;}ee[M*2];
void add(int x,int y,int w){
//cout<<x<<" -> "<<y<<" = "<<w<<endl;
ee[++cnt].nxt=head[x],ee[cnt].w=w,ee[cnt].to=y,head[x]=cnt;}
struct node{
int x,y,id;
}p[M];
bool cmpx(node a,node b){
return a.x<b.x;
}
bool cmpy(node a,node b){
return a.y<b.y;
}
int vs[M];
ll d[M];
priority_queue<pli,vector<pli>,greater<pli> >q;
void dij(int s,int t){
memset(d,0x3f,sizeof(d));
q.push({0,s});d[s]=0;
while(!q.empty()){
pli tp = q.top();q.pop();
int x=tp.second;
if(vs[x])continue;
vs[x]=1;
for(int i=head[x];i;i=ee[i].nxt){
int y=ee[i].to,w=ee[i].w;
if(d[y]>d[x]+w){
d[y]=d[x]+w;
q.push({d[y],y});
}
}
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int n,m,tx,ty,sx,sy;
cin>>n>>m;
cin>>sx>>sy>>tx>>ty;
for(int i=1;i<=m;i++){
cin>>p[i].x>>p[i].y;
p[i].id=i;
}
sort(p+1,p+1+m,cmpx);
for(int i=1;i<=m;i++){
if(i>1)add(p[i].id,p[i-1].id,p[i].x-p[i-1].x);
if(i<m)add(p[i].id,p[i+1].id,p[i+1].x-p[i].x);
}
sort(p+1,p+1+m,cmpy);
for(int i=1;i<=m;i++){
if(i>1)add(p[i].id,p[i-1].id,p[i].y-p[i-1].y);
if(i<m)add(p[i].id,p[i+1].id,p[i+1].y-p[i].y);
}
int s=m+1,t=m+2;
add(s,t,abs(sx-tx)+abs(sy-ty));
for(int i=1;i<=m;i++)
add(s,p[i].id,min(abs(p[i].x-sx),abs(p[i].y-sy))),
add(p[i].id,t,abs(p[i].x-tx)+abs(p[i].y-ty));
dij(s,t);
cout<<d[t]<<endl;
return 0;
}