• 2018/08/08 学习总结


    快速幂

    输入a,b,p;
    求a的b次幂对p求余。
    把b拆成二进制数,通过位运算得到最低位来巧妙降低复杂度。

    int a,b,p;
    cin>>a>>b>>p;
    int ans = 1;
    for(;b;b>>=1)
    {
    	if(b&1)
    		ans = (long long)ans*a%p;
    	a = (long long)a*a%p;
    }
    

    成对变换

    对于非负整数n

    • 若n为偶数,则n^1等于n+1
    • 若n为奇数,则n^1等于n-1

    lowbit运算

    lowbit(n)定义为非负整数n在二进制表示下“最低位的1及其后边所有的0”构成的数值。

    lowbit(n) = n&(-n);

    原理:计算机中数值都由补码形式储存,而负数的补码为原码取反加一。假设一个整数0-k-1位都是0,那么他的相反数的补码0-k-1为也都是0,但是第k位为1,k+1之后的与该正数都互为反,所以两者做与运算可以直接求得所求。

    奇怪的汉诺塔

    三个的汉诺塔的递推公式

    f(n) = 2*f(n-1)+1

    但是如果是四个(从A到D)的话,就可以先把n个中的前k个放到一个塔上,另外n-k个都是按照三个汉诺塔的来放到第四个(D),然后再将前k个按照四个柱子的方法移到第四个柱子。

    d(n) = min(2*d(k)+f(n-k))

    其中k < n;

    a[1] = 1;
    b[1] = 1;
    b[0] = 0;
    for(int i=2;i<=12;i++)
    {
        b[i] = 2*b[i-1]+1;
        a[i] = inf;
        for(int j=1;j<=i;j++)
        	a[i] = min(a[i],a[j]*2+b[i-j]);
        
    }
    

    前缀和(poj3263)

    N头牛,告诉最高的牛高H在p处,然后告诉A可以看到B,可以知道B的高大于等于A的高,A与B之间的牛要比A低

    map<pair<int,int>,bool> existed;
    int c[10010],d[10010];
    int main() 
    {
        int n,i,h,r;
        while(cin>>n>>i>>h>>r)
        {
        	int a,b;
        	for(int i=0;i<r;i++)
        	{
        		cin>>a>>b;
        		if(a>b)swap(a,b);
        		if(existed[make_pair(a,b)])continue;
        		d[a+1]--;d[b]++;
        		existed[make_pair(a,b)] = 1;
        	}
        	for(int i=1;i<=n;i++)
        	{
        		c[i] = c[i-1]+d[i];
        		printf("%d
    ",h+c[i]);
        	}
        }
        return 0;
    }
    
    • 输入之后要调整a和b的大小
    • 判重
    • 用另外一个数组记录,然后通过前缀和来表示高度之间的差值(核心)

    递归枚举

    • 递归思路是将基本单元缩小

    从1-n这n个整数中随机选取任意多个,输出所有可能的方案。

    分析

    • 从1-n开始,每个都只有两个选择
    • 对于每两个选择,分别进行后面数字的选择
    • 对于一个数字,做完决策后把痕迹删除
    int n;
    vector<int> chosen;
    void calc(int x)
    {
    	if(x==n+1)//满足条件即输出
    	{
    		for(int i=0;i<chosen.size();i++)
    		printf("%d ",chosen[i]);
    		puts("");//输出完会有回车
    		return ;
    	}
    	calc(x+1);
    	chosen.push_back(x);
    	calc(x+1);
    	chosen.pop_back();//一定要消除痕迹
    }
    int main() 
    {
    	while(cin>>n)
        	calc(1);
        return 0;
    }
    

    递归实现排列型枚举

    从1-n 这n(n < 10)个整数排除一行后随机打乱顺序,输出所有可能的次序

    • 先排好n-1,然后对于第n个有选哪个的问题,所以要遍历剩下的
    • 要记录之前选过的,需要一个chosen数组
    • 最后要删除标记
    int n;
    int order[21];
    int chosen[21];
    void calc(int k)
    {
    	if(k==n+1)
    	{
    		for(int i=1;i<=n;i++)
    			printf("%d ",order[i]);
    		puts("");
    		return;
    	}
    	for(int i=1;i<=n;i++)
    	{
    		if(chosen[i])
    			continue;
    		order[k] = i;
    		chosen[i] = 1;
    		calc(k+1);
    		chosen[i] = 0;
    	}
    }
    
    int main() 
    {
    	while(cin>>n)
    		calc(1);
        return 0;
    }
    

    Fractal Streets(poj3889)

    题意不在赘述

    递归,从n递归到1,解决最小问题,经过一步一步转化得到n级城市的坐标。

    • 房屋必须要从0开始,因为要方便确定属于哪一个区
    • 在城市升级过程中要格外小心坐标转换
    • 最后计算距离时sqrt的输出
    pair<long long,long long> calc(int n,long long m)
    {
    	if(n==0)
    		return make_pair(0,0);
    	long long len = 1<<(n-1),cnt = 1<<(2*n-2);
    	pair<long long,long long> pos = calc(n-1,m%cnt);
    	long long x = pos.first,y = pos.second;
    	long long z = m/cnt;
    	if(z==0)
    		return make_pair(y,x);
    	if(z==1)
    		return make_pair(x+len,y);
    	if(z==2)
    		return make_pair(x+len,y+len);
    	if(z==3)
    		return make_pair(len-y-1,2*len-x-1);
    }
    
    int main() 
    {
        int t;
        cin>>t;
        while(t--)
        {
        	int n;
        	long long h,o;
        	cin>>n>>h>>o;
        	pair<long long,long long>a = calc(n,h-1);
        	//cout<<a.first<<a.second<<endl;
        	pair<long long,long long>b = calc(n,o-1);
        	//cout<<b.first<<b.second<<endl;
        	printf("%.0f
    ",sqrt((double)(a.first-b.first)*(a.first-b.first)+(double)(a.second-b.second)*(a.second-b.second))*10) ;
        	//cout<<dis*10<<endl;
        }
        return 0;
    }
    

    总结

    • 今天虽然只看了二十页,有些难题还没有AC,样例过了始终无法AC。
    • 二进制的部分要经常复习
    • 递推和递归条件一开始就要清楚,遇到答案不符的情况可以输出过程量测试找bug
    • 尽量不调试。
    注:转载请注明出处
  • 相关阅读:
    SpringCloud之Eureka注册中心
    微服务入门概念
    迁移桌面程序到MS Store(3)——开机自启动
    迁移桌面程序到MS Store(2)——Desktop App Converter
    迁移桌面程序到MS Store(1)——通过Visual Studio创建Packaging工程
    [UWP]涨姿势UWP源码——适配电脑和手机
    [UWP]涨姿势UWP源码——UI布局
    微软2017MVP大礼包拆箱攻略
    [UWP]涨姿势UWP源码——Unit Test
    [UWP]涨姿势UWP源码——IsolatedStorage
  • 原文地址:https://www.cnblogs.com/1625--H/p/9446036.html
Copyright © 2020-2023  润新知