ECNU OJ学习记录

一、 常用算法

1. 素数,筛选法

int num[20010];
void prime() {
	num[1] = 1;
	for (int i = 2; i < 20010; i++) {
		if (num[i] == 0) {
			num[i] = 1;
			for (int j = i * i; j < 20010; j+=i) {
				num[j] = -1;
			}
		}
	}
}

2. 最大公约数,辗转相除法

//方法一
int gcd(int n,int m){
	if(n % m == 0){
		return m;
	}
	return gcd(m,n%m);
}
//方法二,方法一的简化版
int gcd(int n, int m) {
	return m ? gcd(m, n % m) : n;
}

//求多个数的最大公约数
int gcds(int arr[], int m) {
	int tem = arr[0];
	for (int i = 1; i < m; i++) {
		tem = gcd(tem,arr[i]);//这里的gcd函数与上文辗转相除一致
	}
	return tem;
}

最小公倍数

int lcm(int a,int b){
 	return a*b/gcd(a,b);
}

3. 最大公共子序列

无需连续

class Solution {
public:
    /**
     * longest common subsequence
     * @param s1 string字符串 the string
     * @param s2 string字符串 the string
     * @return string字符串
     */
    string LCS(string s1, string s2) {
        int m = s1.length(),n = s2.length();
        if(m==0 || n==0)
            return "-1";
        vector<vector<int>> dp(m+1,vector<int>(n+1,0));
        vector<vector<char>> turn(m,vector<char>(n,0));
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                if(s1[i]==s2[j])
                    dp[i+1][j+1] = dp[i][j] + 1;
                else
                    if(dp[i][j+1]>dp[i+1][j])
                        dp[i+1][j+1] = dp[i][j+1], turn[i][j]='U';
                    else
                        dp[i+1][j+1] = dp[i+1][j], turn[i][j]='L';
            }
        }
        if(dp[m][n]==0)
            return "-1";
        string ans;
        // search
        for(int i = m-1, j = n-1;i>=0&&j>=0;){
            if(turn[i][j] == 'U') i--;
            else if(turn[i][j] == 'L') j--;
            else{
                ans.push_back(s1[i]);
                i--;
                j--;
            }
        }
        // output
        reverse(ans.begin(),ans.end());
        return ans;
    }
};

最大公共子串

需要连续

class Solution {
public:
    /**
     * longest common substring
     * @param str1 string字符串 the string
     * @param str2 string字符串 the string
     * @return string字符串
     */
string LCS(string str1, string str2) {
    int m = str1.length(), n = str2.length();
    if (m == 0 || n == 0)
        return nullptr;
    vector<vector<int>> dp(m, vector<int>(n));
    int index = 0, maxsum = 0;
    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) {
            if (str1[i] == str2[j]) {
                if (i == 0 || j == 0)
                    dp[i][j] = 1;
                else
                    dp[i][j] = dp[i - 1][j - 1] + 1;
                if (maxsum < dp[i][j])
                    maxsum = dp[i][j], index = i;
            }
        }
    }
    return maxsum == 0 ? "-1" : str1.substr(index - maxsum + 1, maxsum);

}
};

二、重点题

2877 排序题,只限制相邻的可以交换位置,求最小的交换次数。其实就是求逆序数

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

int main() {
	int T, n;
	cin >> T;
	int num[1010];
	for (int i = 1; i <= T; i++) {
		cin >> n;
		int sum = 0;
		for (int j = 0; j < n; j++) {
			cin >> num[j];
		}
		for (int j = 0; j < n; j++) {
			for (int m = j + 1; m < n; m++) {
				if (num[j] > num[m])
					sum++;
			}
		}
		cout << "Scenario #" << i << ":" << endl;
		cout << sum << endl << endl;
	}
	return 0;
}

2971 数学题,数字上所有位数加起来能被3整除时,这个数能被3整除

考虑样例中的2 8,那么相当于考虑18,28,38,…,98中有几个能被3整除。
我们知道当数字上所有位数加起来能被3整除时,这个数能被3整除,而我们可以将1-9分成三组:369,147,258,分别是模3余0,1,2三种情况,因为个位不变的,那么不管个位是几,总能找到合适的一组去匹配它,使得其加上个位后被3整除,所以个数就是3.
容易知道这个结论是可以推广到n位的.
那么我们只需要计算99…9-10…0中能被3整除的有几个数,即(99…9-10…0+1)/3

#include <bits/stdc++.h>
using namespace std;
int main() {
    int T;
    cin >> T;
    for(int a = 0; a < T; ++a){
        int c, w;
        cin >> c >> w;
        int start = (int)pow(10, c-2);
        int end = 0;
        for(int i = 0; i < c-1; ++i){
            end = end*10+9;
        }
        int count = end-start+1;
        printf("case #%d:\n%d\n", a, count/3);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值