• 牛客寒假基础训练营3


    牛客寒假基础训练营3


    A:牛牛的DRB迷宫I

    一道记忆话搜索题,对于一个点(x,y)考虑(x-1,y)和(x,y-1),根据是否允许移动进行更新,如果(x-1,y)不等于'R'则(x,y)位置加上(x-1,y)处的值,如果(x,y-1)处不等于'D'则(x,y)处加上(x,y-1)处的值,一直这样更新下去,注意取模就可以了。

    /*************************************************
    * @Author: maple
    * @Date:   2020-02-08 12:12:02
    * @Last Modified by:   maple
    * @Last Modified time: 2020-02-08 13:10:23
    * @Mark	
    *************************************************/
    #include <bits/stdc++.h>
    #define CSE(x,y) memset(x,y,sizeof(x))
    #define lowbit(x) x&(-x)
    #define FAST ios::sync_with_stdio(false);cin.tie(0);
    #define INF 0x3f3f3f3f
    using namespace std;
    
    typedef long long ll;
    typedef pair<int,int> pii;
    typedef pair<ll,ll> pll;
    
    const int maxn=111;
    
    ll mp[maxn][maxn],n,m;
    char ss[maxn][maxn];
    ll mod=1e9+7;
    
    int main()
    {
    	FAST;
    	#ifndef ONLINE_JUDGE
    	freopen("in.in","r",stdin);
    	#endif
    	cin>>n>>m;
    	for(int i=0;i<n;i++){
    		cin>>ss[i];
    	}
    	CSE(mp,0);
    	mp[0][0]=1;
    	for(int i=1;i<m;i++){
    		if(ss[0][i-1]!='D')
    			mp[0][i]=(mp[0][i]+mp[0][i-1])%mod;
    	}
    	for(int i=1;i<n;i++){
    		if(ss[i-1][0]!='R')
    			mp[i][0]=(mp[i][0]+mp[i-1][0])%mod;
    	}
    	for(int i=1;i<n;i++){
    		for(int j=1;j<m;j++){
    			if(ss[i-1][j]!='R')
    				mp[i][j]=(mp[i][j]+mp[i-1][j])%mod;
    			if(ss[i][j-1]!='D')
    				mp[i][j]=(mp[i][j]+mp[i][j-1])%mod;
    		}
    	}
    	cout<<mp[n-1][m-1]%mod<<endl;
    	return 0;
    }
    

    B:牛牛的DRB迷宫II


    C:牛牛的数组越位

    这个题写法应该很多,我是选择了把二维座标直接转化为一维座标,如果转化成一维出现越界那么就是RE,如果转换成一维座标没有问题就是AC且在二维座标下没有问题,如果二维座标下有问题,那么就是UB了。

    /*************************************************
    * @Author: maple
    * @Date:   2020-02-08 13:37:12
    * @Last Modified by:   maple
    * @Last Modified time: 2020-02-08 13:55:13
    * @Mark	
    *************************************************/
    #include <bits/stdc++.h>
    #define CSE(x,y) memset(x,y,sizeof(x))
    #define lowbit(x) x&(-x)
    #define FAST ios::sync_with_stdio(false);cin.tie(0);
    #define INF 0x3f3f3f3f
    using namespace std;
    
    typedef long long ll;
    typedef pair<int,int> pii;
    typedef pair<ll,ll> pll;
    
    const int maxn=1111111;
    
    int arr[maxn],n,m,p;
    
    int main()
    {
    	FAST;
    	#ifndef ONLINE_JUDGE
    	freopen("in.in","r",stdin);
    	#endif
    	int t;
    	cin>>t;
    	while(t--){
    		CSE(arr,0);
    		bool ub=false,re=false;
    		cin>>n>>m>>p;
    		for(int i=0;i<p;i++){
    			int x,y,val;
    			cin>>x>>y>>val;
    			if(x<0||y<0||x>=n||y>=m){
    				if(1ll*x*m+y<0||1ll*x*m+y>=1ll*n*m){
    					re=true;
    				}
    				else{
    					arr[x*m+y]=val;
    					ub=true;
    				}
    			}
    			else{
    				arr[x*m+y]=val;
    			}
    		}
    		if(re){
    			cout<<"Runtime error"<<endl;
    		}
    		else{
    			for(int i=0;i<n;i++){
    				for(int j=0;j<m;j++){
    					if(j!=0) cout<<" ";
    					cout<<arr[i*m+j];
    				}
    				cout<<endl;
    			}
    			if(ub){
    				cout<<"Undefined Behaviour"<<endl;
    			}
    			else
    				cout<<"Accepted"<<endl;
    		}
    	}
    	return 0;
    }
    

    D:牛牛与二叉树的数组存储

    这题只是简单介绍了一下二叉树的结构和线性存储,可以理解成把一颗二叉树的根存到1处之后其左子树座标为i*2其右子树座标为i*2+1,由此存储这颗树,没有节点的位置为-1,根据这个规律,我们只需要统计不为-1的个数即为数的节点个数也就是尺寸,之后根节点就是1处的值,然后对于每一个不为-1的点我们用数组记录,这个点的父节点是谁和其左右儿子分别是谁,之后按要求输出就可了,虽然说起来可能有点乱,但是看代码就很容易明白了。

    /*************************************************
    * @Author: maple
    * @Date:   2020-02-08 14:31:43
    * @Last Modified by:   maple
    * @Last Modified time: 2020-02-08 14:40:31
    * @Mark	
    *************************************************/
    #include <bits/stdc++.h>
    #define CSE(x,y) memset(x,y,sizeof(x))
    #define lowbit(x) x&(-x)
    #define Abs(x) x>=0?x:(-x)
    #define FAST ios::sync_with_stdio(false);cin.tie(0);
    #define INF 0x3f3f3f3f
    using namespace std;
    
    typedef long long ll;
    typedef pair<int,int> pii;
    typedef pair<ll,ll> pll;
    
    const int maxn=333333;
    
    int tree[maxn],n;
    int father[maxn],lchild[maxn],rchild[maxn];
    
    int main()
    {
    	FAST;
    	#ifndef ONLINE_JUDGE
    	freopen("in.in","r",stdin);
    	#endif
    	CSE(tree,-1);
    	cin>>n;
    	for(int i=1;i<=n;i++){
    		cin>>tree[i];
    	}
    	int size=0;
    	for(int i=1;i<=n;i++){
    		if(tree[i]!=-1){
    			size++;
    			father[tree[i]]=tree[i/2];
    			lchild[tree[i]]=tree[i*2];
    			rchild[tree[i]]=tree[i*2+1];
    		}
    	}
    	cout<<"The size of the tree is "<<size<<endl;
    	cout<<"Node "<<tree[1]<<" is the root node of the tree"<<endl;
    	for(int i=1;i<=size;i++){
    		printf("The father of node %d is %d, the left child is %d, and the right child is %d
    ",i,father[i],lchild[i],rchild[i]);
    	}
    	return 0;
    }
    

    E:牛牛的随机数


    这题我们可以去考虑前缀的方法去考虑这个问题,我们计算出每一个值它前面和它组成link的点所产生的能量之和,当遍历到下一个link点时,这个点处的结果为前一个link点的值加上上一个link点到这个link点的距离乘以之前link点的个数即可算出该点存在所产生的link值,最后遍历数组把所有能量值加起来就可以了。

    /*************************************************
    * @Author: maple
    * @Date:   2020-02-08 13:55:56
    * @Last Modified by:   maple
    * @Last Modified time: 2020-02-08 14:21:48
    * @Mark	
    *************************************************/
    #include <bits/stdc++.h>
    #define CSE(x,y) memset(x,y,sizeof(x))
    #define lowbit(x) x&(-x)
    #define Abs(x) x>=0?x:(-x)
    #define FAST ios::sync_with_stdio(false);cin.tie(0);
    #define INF 0x3f3f3f3f
    using namespace std;
    
    typedef long long ll;
    typedef pair<int,int> pii;
    typedef pair<ll,ll> pll;
    
    const int maxn=111111;
    const ll  mod = 1e9+7;
    
    ll arr[maxn],num=0,len=0,n,last=0;
    string str;
    
    int main()
    {
    	FAST;
    	#ifndef ONLINE_JUDGE
    	freopen("in.in","r",stdin);
    	#endif
    	cin>>n>>str;
    	for(int i=0;i<n;i++){
    		if(str[i]=='1'){
    			arr[i]=(last+num*len%mod)%mod;
    			num++;
    			len=0;
    			last=arr[i];
    		}
    		len++;
    	}
    	ll ans=0;
    	for(int i=0;i<n;i++){
    		if(str[i]=='1')
    			ans=(ans+arr[i])%mod;
    	}
    	cout<<ans<<endl;
    	return 0;
    }
    


    H:牛牛的k合因子

    先说我是怎么想的,对于一个数,我们做质因数分解,分解过程中。记录合数出现的个数,同时质因数分解可以求得该数的因子个数,然后用因子个数减去合数因子个数就是()合因子数,其实就是对题目进行了一个翻译,用埃氏筛的方法很轻送就过了。

    这里贴上题解的解释,可是十分简短了

    埃式筛筛出质数,然后对于合数再筛一遍,然后统计每个数字被筛到的次数。桶排序一下即可。

    /*************************************************
    * @Author: maple
    * @Date:   2020-02-08 13:10:59
    * @Last Modified by:   maple
    * @Last Modified time: 2020-02-08 13:32:07
    * @Mark	
    *************************************************/
    #include <bits/stdc++.h>
    #define CSE(x,y) memset(x,y,sizeof(x))
    #define lowbit(x) x&(-x)
    #define FAST ios::sync_with_stdio(false);cin.tie(0);
    #define INF 0x3f3f3f3f
    using namespace std;
    
    typedef long long ll;
    typedef pair<int,int> pii;
    typedef pair<ll,ll> pll;
    
    const int maxn=111111;
    
    int proce(int x){
    	int all=1,pr=1;
    	for(int i=2;i*i<=x;i++){
    		int mid=1;
    		if(x%i==0)
    			pr++;
    		while(x%i==0){
    			x/=i;
    			mid++;
    		}
    		all*=mid;
    	}
    	if(x>1){
    		pr++;
    		all=all*2;
    	}
    	return all-pr;
    }
    
    int box[maxn];
    
    int main()
    {
    	FAST;
    	#ifndef ONLINE_JUDGE
    	freopen("in.in","r",stdin);
    	#endif
    	int n,m;
    	cin>>n>>m;
    	CSE(box,0);
    	for(int i=1;i<=n;i++){
    		//cout<<i<<":"<<proce(i)<<endl;
    		box[proce(i)]++;
    	}
    	while(m--){
    		int k;
    		cin>>k;
    		cout<<box[k]<<endl;
    	}
    	return 0;
    }
    

    I:牛牛的汉诺塔

    额,对于这个题,我也是呵呵我自己了,这个题我是去研究了答案的规律然后总结出了通相公式,直接算出来的,虽然解释起来很简单,但是找通相公式的过程可谓是相当的凄惨。。。。。

    题解讲了两种方法,记忆化搜索和递推(借助矩阵快速幂),这里贴上代码。

    通相公式:

    /*************************************************
    * @Author: maple
    * @Date:   2020-02-08 15:15:42
    * @Last Modified by:   maple
    * @Last Modified time: 2020-02-08 15:49:46
    * @Mark	
    *************************************************/
    #include <bits/stdc++.h>
    #define CSE(x,y) memset(x,y,sizeof(x))
    #define lowbit(x) x&(-x)
    #define Abs(x) x>=0?x:(-x)
    #define FAST ios::sync_with_stdio(false);cin.tie(0);
    #define INF 0x3f3f3f3f
    using namespace std;
    
    typedef long long ll;
    typedef pair<int,int> pii;
    typedef pair<ll,ll> pll;
    
    const int maxn=11111;
    
    ll arr[10],n;
    
    ll qpow(ll a,ll b){
    	ll base=1;
    	while(b){
    		if(b&1){
    			base*=a;
    		}
    		a*=a;
    		b>>=1;
    	}
    	return base;
    }
    
    
    int main()
    {
    	FAST;
    	#ifndef ONLINE_JUDGE
    	freopen("in.in","r",stdin);
    	#endif
    	cin>>n;
    	arr[1]=(qpow(2,2*(n/2-1)+3)+3*(n/2-1)+1)/9;
    	arr[2]=(qpow(2,2*((n-1)/2-1)+3)+3*((n-1)/2-1)+1)/9*2+1;
    	arr[3]=(qpow(4,(n-1)/2+1)-3*((n-1)/2)-4)/9;
    	arr[4]=arr[1];
    	arr[6]=arr[3];
    	arr[5]=((qpow(4,(n-2)/2+1)-3*((n-2)/2)-4)/9)*2;
    	cout<<"A->B:"<<arr[1]<<endl;
    	cout<<"A->C:"<<arr[2]<<endl;
    	cout<<"B->A:"<<arr[3]<<endl;
    	cout<<"B->C:"<<arr[4]<<endl;
    	cout<<"C->A:"<<arr[5]<<endl;
    	cout<<"C->B:"<<arr[6]<<endl;
    	cout<<"SUM:"<<arr[1]+arr[2]+arr[3]+arr[4]+arr[5]+arr[6]<<endl;
    	return 0;
    }
    

    比赛场上想到这种解法可以说是相当亏了

    题解

    #include<bits/stdc++.h>
    using namespace std;
    struct node
    {
     long long data[6];
     node()
     {
         memset(data,0,sizeof(data));
     }
     //A->B      0
     //A->C      1
     //B->A      2
     //B->C      3
     //C->A      4
     //C->B      5
    };
    node operator + (const node &A,const node &B)
    {
     node C;
     for(int i=0;i<6;++i)
     {
         C.data[i]=A.data[i]+B.data[i];
     }
     return C;
    }
    void moveto(int x,int y,node &temp)
    {
     if(x==0&&y==1)++temp.data[0];
     if(x==0&&y==2)++temp.data[1];
     if(x==1&&y==0)++temp.data[2];
     if(x==1&&y==2)++temp.data[3];
     if(x==2&&y==0)++temp.data[4];
     if(x==2&&y==1)++temp.data[5];
     return;
    }
    node dp[3][3][3][105];
    bool vis[3][3][3][105];
    node hanoi(int a,int b,int c,int n)
    {
     if (vis[a][b][c][n])return dp[a][b][c][n];
     if (n==1)
     {
         moveto(a,c,dp[a][b][c][n]);
         vis[a][b][c][n]=true;
         return dp[a][b][c][n];
     }
     node temp;
     temp=temp+hanoi(a,c,b,n-1);
     moveto(a,c,temp);
     temp=temp+hanoi(b,a,c,n-1);
     vis[a][b][c][n]=true;
     return dp[a][b][c][n]=temp;
    }
    int n;
    int main()
    {
     scanf("%d",&n);
     node ans=hanoi(0,1,2,n);
     printf("A->B:%lld
    ",ans.data[0]);
     printf("A->C:%lld
    ",ans.data[1]);
     printf("B->A:%lld
    ",ans.data[2]);
     printf("B->C:%lld
    ",ans.data[3]);
     printf("C->A:%lld
    ",ans.data[4]);
     printf("C->B:%lld
    ",ans.data[5]);
     printf("SUM:%lld
    ",(1LL<<n)-1);
    }
    
    #include <map>
    #include <set>
    #include <ctime>
    #include <stack>
    #include <cmath>
    #include <queue>
    #include <bitset>
    #include <string>
    #include <vector>
    #include <cstdio>
    #include <cctype>
    #include <fstream>
    #include <cstdlib>
    #include <sstream>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <iomanip>
    using namespace std;
    #define LL long long
    const int INF = 0x3f3f3f3f;     ///1 061 109 567
    const int negative_infinite = 0xcfcfcfcf;   ///-808 464 433
    const double pi = acos(-1);
    const int mod = 1e9 + 7;
    const double eps = 1e-8;
    const int MAXN = 1e5 + 117;
    const int MAXM = 2e5 + 117;
    
    int n;
    LL dp[7][77][7];
    /*
    A B 0
    A C 1
    B A 2
    B C 3
    C A 4
    C B 5
    */
    int main() {
     scanf("%d", &n);
     memset(dp, 0, sizeof(dp));
     for(int i = 0; i < 6; i++) dp[i][1][i] = 1;
     for(int i = 2; i <= n; i++) {
         for(int j = 0; j < 6; j++) dp[j][i][j]++;
    
         for(int j = 0; j < 6; j++) dp[0][i][j] += dp[1][i - 1][j] + dp[5][i - 1][j];
         for(int j = 0; j < 6; j++) dp[1][i][j] += dp[0][i - 1][j] + dp[3][i - 1][j];
         for(int j = 0; j < 6; j++) dp[2][i][j] += dp[3][i - 1][j] + dp[4][i - 1][j];
         for(int j = 0; j < 6; j++) dp[3][i][j] += dp[2][i - 1][j] + dp[1][i - 1][j];
         for(int j = 0; j < 6; j++) dp[4][i][j] += dp[5][i - 1][j] + dp[2][i - 1][j];
         for(int j = 0; j < 6; j++) dp[5][i][j] += dp[4][i - 1][j] + dp[0][i - 1][j];
     }
     printf("A->B:%lld
    ", dp[1][n][0]);
     printf("A->C:%lld
    ", dp[1][n][1]);
     printf("B->A:%lld
    ", dp[1][n][2]);
     printf("B->C:%lld
    ", dp[1][n][3]);
     printf("C->A:%lld
    ", dp[1][n][4]);
     printf("C->B:%lld
    ", dp[1][n][5]);
     printf("SUM:%lld
    ", ((LL)1 << n) - 1);
     return 0;
    }
    

    J:牛牛的宝可梦Go


  • 相关阅读:
    判断有向无环图(DAG)
    单向连通图 Going from u to v or from v to u? poj2762
    百度地图的实时路况 2016 计蒜之道 复赛
    快速模取幂
    fibonacci数列(二)_矩阵快速幂
    数与矩阵快速幂基本知识
    Brute-force Algorithm_矩阵快速幂&&欧拉公式*****
    Nearest number
    Zipper_DP
    Jumping Cows_贪心
  • 原文地址:https://www.cnblogs.com/LeafLove/p/12369553.html
Copyright © 2020-2023  润新知