upc- 2020年春混合个人训练第三场 A G

A: 奇怪的道路

从前,有一座网格城市,城市中每个房子占据一个正方形小格子的中心,每个正方形小格子的边长均为1。
这座城市道路的设计方式是这样的,首先,定义(a)图为一个基本图形,其阶为1,之后,将(a)图中每一个房子都用一个基本图形代替,得到(b)图,那么(b)图的阶即为2,再将(b)图中的每一个房子都用基本图形替代,得到阶为3的(c)图,以此类推,只要知道这座城市的阶n,就可以知道它的道路设计。

这种七拐八弯的道路设计使得这座城市之间的道路交通运输相当不便,于是该市的市长决定改造一下这座城市的道路,但在此之前他需要做一系列的评估,比如这座网格城市中,连接第i1行第j1列的房屋与第i2行第j2列的房屋之间(两座房屋可能相同)的道路有多长,由于这种道路设计太过奇怪,人力难以计算,于是这个任务就交给作为软件工程师的你了。

输入

每个测试点第一行有两个正整数n,T,表示城市的阶数和询问数。
接下来T行,每行4个正整数i1,j1,i2,j2,表示要查询的两个房屋的坐标。

输出

对每个询问输出一行相应的值表示答案。

样例输入 Copy

2 4
2 1 3 1
3 2 2 2
2 3 3 3
3 4 2 4

样例输出 Copy

13
11
1
3

提示

样例解释:
样例对应题目中的(b)图。
第一个询问问的是图中编号为2的房子与编号为15的房子的距离。
第二个询问问的是图中编号为14的房子与编号为3的房子的距离。
第三个询问问的是图中编号为8的房子与编号为9的房子的距离。
第四个询问问的是图中编号为10的房子与编号为7的房子的距离。

对于100%的数据,均有1≤n≤15,1≤i1,j1,i2,j2≤2n,1≤T≤10000。

题意:给定一个图,给你规定规律如上图,给定t次询问,每次问两点坐标之间的距离。

 

思路:首先可以看出图的大小为pow(4,n)。所以打表是不可以了,然后这个规律也很清晰啊,类似于降维,每一层就是由上一层的四个转换而来,所以我们从n再给他逆回去,每次确定中心点坐标,然后确定四个象限,1,2,3,4。就是那个坐标转换可能有些难画。(其实就是那个第四象限需要+1那里,别的都还好);

 

#pragma GCC optimize("Ofast","unroll-loops","omit-frame-pointer","inline")
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
inline bool read(ll &num){char in;bool IsN=false;in=getchar();if(in==EOF) return false;while(in!='-'&&(in<'0'||in>'9')) in=getchar();if(in=='-'){ IsN=true;num=0;}else num=in-'0';while(in=getchar(),in>='0'&&in<='9'){num*=10,num+=in-'0';}if(IsN) num=-num;return true;};
#define rep(i,a,n) for(ll i=a;i<=n;i++)
#define per(i,a,n) for(ll i=a;i>=1;i--)
#define mem(a,b) memset(a,b,sizeof(a)) 
const ll INF=5e18+7;
const ll mod=1e9+7;
const ll maxx=2e5+5;
/*
  i am hengheng
*/
//ll head[maxx];ll deep[maxx];ll vis[maxx];ll dis[maxx];map<ll,ll>mp;vector<ll>v[maxx];
ll n,m;
ll dfs(ll n,ll x,ll y)
{
	// 
	if(n==0)
        return 1;
    ll mid=pow(2,n-1);
	ll sum=mid*mid;
    if(x<=mid&&y<=mid) // 1
        return dfs(n-1,y,x);
    else if(x<=mid&&y>mid)// 2
        return sum+dfs(n-1,x,y-mid);
    else if(x>mid&&y>mid)//3
        return 2*sum+dfs(n-1,x-mid,y-mid);
    else// 4
        return 3*sum+dfs(n-1,mid+1-y,mid+mid+1-x);
}
int main()
{
    
    ll i,j,k;
    cin>>n>>m;
   	rep(i,1,m)
   	{
   		ll l1,l2,r1,r2;
   		cin>>l1>>r1>>l2>>r2;
		cout<<abs(dfs(n,l2,r2)-dfs(n,l1,r1))<<endl;	
	}
   	
    return 0;
}

C:(待补)

 

G

 艰难取舍

时间限制: 1 Sec  内存限制: 128 MB
[提交] [状态]

题目描述

由于hyf长得实在是太帅了,英俊潇洒,风流倜傥,人见人爱,花见花开,车见车载。
有一群MM排队看hyf。每个MM都有自己独特的风格,由于hyf有着一颗包容的心,所以,什么风格的MM他都喜欢……
但是,hyf有一个特别的要求,他不希望总是看到风格得差不多的MM,更加特别的是,如果两个MM风格完全一样,hyf不会有任何意见。
现在,hyf希望从去看他的MM中,去掉一些MM,从而使得相邻2个MM的风格值的差(绝对值)不为1。自然地,hyf希望去掉的MM越少越好。

输入

第一行一个整数N;
第2~N+1行N个整数,第i个为ci。表示第i个MM的风格值。

输出

一个数,表示最少要去掉的MM数。

样例输入 Copy

6
4
2
2
1
1
1

样例输出 Copy

2

提示

对于30%的数据,N≤20
对于70%的数据,N≤100,ci≤2000
对于100%的数据,N≤1000,0≤ci≤2000

一想就n方。对于一个点,直接找他前面的所有点,如果可以,则这个点的状态为前点+1,最后找到最长的用n减去即可。

#pragma GCC optimize("Ofast","unroll-loops","omit-frame-pointer","inline")
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
inline bool read(ll &num){char in;bool IsN=false;in=getchar();if(in==EOF) return false;while(in!='-'&&(in<'0'||in>'9')) in=getchar();if(in=='-'){ IsN=true;num=0;}else num=in-'0';while(in=getchar(),in>='0'&&in<='9'){num*=10,num+=in-'0';}if(IsN) num=-num;return true;};
#define rep(i,a,n) for(ll i=a;i<=n;i++)
#define per(i,a,n) for(ll i=a;i>=1;i--)
#define mem(a,b) memset(a,b,sizeof(a)) 
const ll INF=5e18+7;
const ll mod=1e9+7;
const ll maxx=2e5+5;
/*
  i am hengheng
*/
//ll head[maxx];ll deep[maxx];ll vis[maxx];ll dis[maxx];map<ll,ll>mp;vector<ll>v[maxx];
ll n,m;
ll a[maxx];
ll dp[maxx];
int main()
{
     
    ll i,j,k;
    cin>>n;
    rep(i,1,n)
    {
        cin>>a[i];
        dp[i]=1;
    }
    ll maxl=0;
    dp[0]=0;
    rep(i,1,n)
    {
        rep(j,1,i-1)
        {
            if(a[i]==a[j]+1||a[i]==a[j]-1)
            {
                ;
            }
            else dp[i]=max(dp[i],dp[j]+1);
        }
        maxl=max(maxl,dp[i]);
        //printf("%lld\n",dp[i]);
    }
    if(n==1) printf("0\n");
    else
    cout<<n-maxl<<endl;
    return 0;
}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值