假期总结(2)

RPG难题


/*
先列出前面几项观察下规律,	a[1] = 3, a[2] = 6, a[3] = 6; 
按照一般的思路,找涂n个方格的方法数,可以看涂n-1个方格的方法数,然后涂第n个方格多了多少种方法
根据题中“要求任何相邻的方格不能同色,且首尾两格也不同色 ”可知
当n大于等于4时,第1格到第n-1格(大于等于3)才不是相邻的
思路来源:涂好了前n-1格的基础上涂第n格,保证第1格和第n格颜色不同,且第n-1格与第n格颜色不同
          所以需要去分类讨论第1格和第n-1格的颜色是否相同 
所以得到一个讨论的条件:(当n大于等于4时)(总共有3种颜色) 
1.第1格与第n-1格同色时,涂第n格可以有2种方法,此时满足第1格与第n格颜色不同,第n-1格与第n格颜色不同
  而此时涂前n-1格的方法数实际上只是涂前n-2格的方法数(第1格与第n-1格同色),所以有2*a[n-2]种方法 
2.第1格与第n-1格不同色时,涂第n格只能有1种方法,此时满足第1格与第n格颜色不同,第n-1格与第n格颜色不同
  而此时涂前n-1格的方法数为a[n-1]
所以涂前n格的方法数为a[n]=a[n-1]+2*a[n-2]
*/
#include <iostream>
using namespace std;
int main(){
	long long a[60];//用long long存取,因为当n较大时数会很大,保险起见
	int n;
	a[1] = 3;
	a[2] = 6;
	a[3] = 6;
	while(cin >> n){
		for(int i = 4; i <= n; i++){
			a[i] = a[i - 1] + 2*a[i - 2];
		}
		cout << a[n] << endl;
	}
	return 0;
}

2049
错排公式:D(n)=(n-1)*(D(n-1)+D(n-2))


#include<stdio.h>
long long swp1(int i);
long long swp2(int a,int b);
int main()
{
    long long k;
    int c,n,m;
    scanf("%d",&c);
    for(int l=0;l<c;l++)
    {
        scanf("%d %d",&n,&m);
        k=swp1(m)*swp2(n,m);
        printf("%lld\n",k);
    }
    return 0;
}
long long swp1(int i)
{
    if(i==1)
    return 0;
    else if(i==2)
    return 1;
    else 
    return (i-1)*(swp1(i-1)+swp1(i-2));
}
long long swp2(int a,int b)
{
    int sum=1;
    for(int j=1;j<=b;j++)
    sum=(sum*(a-b+j))/j;
    return sum;
}
//快速排序
#include <bits/stdc++.h>
using namespace std;
int n;
int arr[1000];
int i,j;
void quick_sort(int arr[], int l, int r)
{
   if(l >= r) return;
   int x = arr[l + r >> 1];
   int i = l - 1, j = r + 1;
   while(i < j)
  {
       do i ++; while(arr[i] < x);
       do j --; while(arr[j] > x);
       if(i < j) swap(arr[i], arr[j]);
  }
   quick_sort(arr, l, j);
   quick_sort(arr, j + 1, r);
}
int main()
{
    cin >> n;
    for (int i = 0;i < n;i++)
        cin >> arr[i];
    quick_sort(arr,0,n-1);
    for (int i = 0;i < n;i++)
        cout << arr[i];
        return 0;
}

2079

#include<stdio.h>
int main()
{
	int n;
	scanf("%d",&n);
	while(n--)
	{
		double h,m,s;
		double y1,y2,y3,y4;
		scanf("%lf%lf%lf",&h,&m,&s);
		if(h>=12)
			h=h-12; 
		y1=s/60;
		y2=(m+y1)/60;
		y3=y2*360;
		y4=(h+y2)*30;
		if(y4>y3)
		{
			if((y4-y3)>180)
				printf("%d\n",int (360-y4+y3));
			else
				printf("%d\n",int (y4-y3));
		}
		else
		{
			if((y3-y4)>180)
				printf("%d\n",int (360-y3+y4));
			else
				printf("%d\n",int (y3-y4));
		}
	}
	return 0;
	}

1. 序列的长度为 5。
  2. 序列中的每个数都是 1 到 10 之间的整数。
  3. 序列中后面的数大于等于前面的数。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

int n, m, res;
int i, j;
char arr[25][25];
int dx[][2] = {0,1,0,-1,1,0,-1,0};
typedef pair<int,int> P;

void dfs(vector<int> path) 
{
    if(path.size() == 5){
        for(int i = 0;i < 5;i ++){
            cout<<path[i]<<" ";
        }
        cout<<endl;
        res++;
        return;
    }
    for(int i = 1; i <= 10; i++){
        if(path.size() == 0){
            path.push_back(i);
            dfs(path);
            path.pop_back();
        } else{
            if(i >= path[path.size() -1 ]){
                path.push_back(i);
                dfs(path);
                path.pop_back();
            }
        }
    }
}

int main(void)
{
    vector<int> path;
    dfs(path);
    cout<<res<<endl;
   
    return 0;
}

//2002

两个字母之间的距离定义为它们在字母表中位置的距离。例如 A 和 C 的距离为 2,L 和 Q 的距离为 5。
  对于一个字符串,我们称字符串中两两字符之间的距离之和为字符串的内部距离。
  例如:ZOO 的内部距离为 22,其中 Z 和 O 的距离为 11。
  请问,LANQIAO 的内部距离是多少?

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

int n, m, res;
int i, j;
char arr[25][25];
int dx[][2] = {0,1,0,-1,1,0,-1,0};
typedef pair<int,int> P;


int main(void)
{
    string s = "LANQIAO";
    //cout << 'Z' - 'O' <<endl;
    int len = s.size();
    for(int i = 0; i < len; i++) {
        for(int j = i + 1; j < len; j++) {
            res += abs(s[i] - s[j]);
        }
    }
    cout<< res <<endl;
   
    return 0;
}

//162

输入的第一行包含两个整数 n, m。
  第二行包含一个整数 t,表示出水管的数量。
  接下来 t 行描述出水管的位置,其中第 i 行包含两个数 r, c 表示第 r 行第 c 列有一个排水管。
  接下来一行包含一个整数 k。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

int a, b, t, r, c, k;
int m, n, res;
int arr[105][105];
int dx[][2] = {0,1,0,-1,1,0,-1,0};
typedef pair<int,int> P;
map<P,int> mp;
queue<P> que;
int sum[10000];
void bfs(){
    while(!que.empty()) {
        P tp = que.front();
        que.pop();
        
        for(int i = 0; i < 4; i++) {
            int xx = tp.first + dx[i][0];
            int yy = tp.second + dx[i][1];
            if(1 <= xx && xx <= n && 1 <= yy && yy <= m && arr[xx][yy] == 0){
                P tmp = make_pair(xx, yy);
				arr[xx][yy] = 1;
                que.push(tmp);
                mp[tmp] = mp[tp] + 1;
                sum[mp[tp] + 1] ++;
            }
        }
    }
    
}

int main(void)
{
    scanf("%d %d %d", &n, &m, &t);
    for(int i = 0; i < t; i++) {
        scanf("%d %d", &r, &c);
        arr[r][c] = 1;
        P st = make_pair(r,c);
        que.push(st);
        mp[st] = 0;
        sum[0] ++;
    }
    scanf("%d", &k);
    bfs();
    for(int i = 0; i <= k; i++)
        res += sum[i];
    printf("%d\n", res);
    return 0;
}
高精度+高精度
vector<int> add(vector<int> A, vector<int> B)
{
    if(A.size() < B.size()) return add(B, A);
    vector<int> C;
    int t = 0;
    for(int i = 0; i < A.size(); i++)
    {
        t += A[i];
        if(i < B.size()) t += B[i];
        C.push_back(t % 10);
        t /= 10;
    }
    if(t) C.push_back(t);
    return C;
}
高精度-高精度
vector<int> sub(vector<int> A, vector<int> B)
{
    vector<int> C;
    int t = 0;
    for(int i = 0; i < A.size(); i++)
    {
        t += A[i];
        if(i < B.size()) t -= B[i];
        C.push_back((t + 10) % 10);
        if(t < 0) t = -1;
        else t = 0;
    }
    
    while(C.size() > 1 && C.back() == 0) C.pop_back();
    return C;
}
高精度*低精度
vector<int> mul(vector<int> A, int b)
{
    vector<int> C;
    int t = 0;
    for(int i = 0; i < A.size() || t; i++)
    {
        if(i < A.size()) t += A[i] * b;
        C.push_back(t % 10);
        t /= 10;
    }
    while(C.size() > 1 && C.back() == 0) C.pop_back();
    return C;
}
高精度/低精度
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

vector<int> div(vector<int> A, int b, int &r)
{
    vector<int> C;
    r = 0;
    for(int i = A.size() - 1; i >= 0; i--)
    {
        r = r * 10 + A[i];
        C.push_back(r / b);
        r = r % b;
    }
    reverse(C.begin(), C.end());
    while(C.size() > 1 && C.back() == 0) C.pop_back();
    return C;
}

int main(void)
{
    string a;
    int b;
    cin >> a >> b;//123456
    vector<int> A, C;
    for(int i = a.size() - 1; i >= 0; i--) A.push_back(a[i] - '0');//654321
    int r;
    C = div(A, b, r);
    for(int i = C.size() - 1; i >= 0; i--) cout << C[i];
    cout << endl << r << endl;
    return 0;
}

输入的第一行包含两个整数 n, m,表示图的大小。
  接下来 n 行,每行 m 个整数,表示方格图中每个点的权值。

#include<bits/stdc++.h>
using namespace std;

int m, n;
int arr[50][50];
int dp[50][50];

int main(void)
{
    scanf("%d %d", &n, &m);
    for(int i = 0; i < n; i++)
        for(int j = 0; j < m; j++)
            scanf("%d", &arr[i][j]);
    dp[0][0] = arr[0][0];
    for(int i = 0; i < n; i++) {
        for(int j = 0; j < m; j++) {
            for(int k = 1; k <= 3 ; k++){
                if(i -k >=0) 
                    dp[i][j] = max(dp[i][j], dp[i - k][j] + arr[i][j]);
                if(j - k >=0)
                    dp[i][j] = max(dp[i][j], dp[i][j - k] + arr[i][j]);
                if(i - k >= 0 && j - k >= 0)
                    dp[i][j] = max(dp[i][j], max(dp[i - k][j] + arr[i][j], dp[i][j - k] + arr[i][j]));
                
            }
        }
        
    }
    
    printf("%d\n",dp[n - 1][m - 1]);
    
    return 0;
}

2078

#include <cstdio>
#include <algorithm>
using namespace std;
int main()
{
	int u;
	int n,m;
	int minn;
	scanf ("%d",&u);
	while (u--)
	{
		scanf ("%d %d",&n,&m);
		minn = 100;
		while (n--)
		{
			int t;
			scanf ("%d",&t);
			minn = min (minn , t);
		}
		printf ("%d\n",(100-minn)*(100-minn));
	}
	return 0;
}

埃式筛法

const int N = 1000010;
int n, primes[N], cnt;
bool st[N];

void get_primes(int n)
{
    for(int i = 2; i <= n; i++)
    {
        if(!st[i])
        {
            primes[cnt++] = i;
            for(int j = i + i; j <= n; j += i) st[j] = true;
        }
    }
}

欧拉筛法

const int N = 1000010;
int n, primes[N], cnt;
bool st[N];

void get_primes(int n)
{
    for(int i = 2; i <= n; i++)
    {
        if(!st[i]) primes[cnt++] = i;
        for(int j = 0; primes[j] <= n / i; j++)
        {
            st[primes[j] * i] = true;
            if(i % primes[j] == 0) break;//直到找到i的最小质因子退出循环
        }
    }
}

快速幂

0 <= a, k, p <= 10^9

int qmi(int a, int k, int p)
{
    int res = 1;
    while(k)
    {
        if(k & 1) res = (LL)res * a % p;
        k >>= 1;
        a = (LL)a * a % p;
    }
    retrn res;
}

E题

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <string>
#include <cmath>
#include <queue>
#include <vector>
#include <map>
#include <sstream>
#include <stack>
using namespace std;

const int N = 55;
int n, a[N];

int main(void)
{
    int T;
    cin >> T;
    while(T--)
    {
        int l, r;
        cin >> n;
        for(int i = 0; i < n; i++) cin >> a[i];

        bool flag = false;
        for(int i = 0; i < n; i++)
        {
            if(!flag && a[i]) l = i, flag = true;//找到最左边的1
            if(a[i]) r = i;//找到最右边的1
        }
        
        int res = 0;
        for(int i = l; i <= r; i++)
        {
            if(!a[i]) res++;
        }
        cout << res << endl;
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值