Codeforces Round #675 (Div. 2) A - D

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;
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值