1.Contest2425 - 毕老师算法实验一
传送门在这里
题目总览:
A.排列问题
// 排列问题
// 输入一个可能含有重复字符的字符串,打印出该字符串中所有字符的全排列。
#include<bits/stdc++.h>
using namespace std;
bool IsSwap(vector<char> &chars, int nBegin, int nEnd)
{
for(int i=nBegin; i<nEnd; i++) //记住是<nEnd
{
if(chars[i] == chars[nEnd]) return false;
}
return true;
}
void Perm(vector<char> &chars, int k, int m)
{
if(k==m)
{
for(const char x:chars)
{
cout<<x;
}
cout<<endl;
}
else
{
for(int i=k; i<=m; i++)
{
if(IsSwap(chars, k, i))
{
swap(chars[k], chars[i]);
Perm(chars, k+1, m);
swap(chars[k], chars[i]);
}
}
}
}
void Foo(vector<char> &chars)
{
Perm(chars, 0, chars.size()-1);
}
// 字符串
bool IsSwap(string str, int nBegin, int nEnd)
{
for(int i=nBegin; i<nEnd; i++) //记住是<nEnd
{
if(str[i] == str[nEnd]) return false;
}
return true;
}
void Perm2(string str, int k, int m)
{
if(k==m)
{
cout<<str;
cout<<endl;
}
else
{
for(int i=k; i<=m; i++)
{
if(IsSwap(str, k, i))
{
swap(str[k], str[i]);
Perm2(str, k+1, m);
swap(str[k], str[i]);
}
}
}
}
void Foo2(string str)
{
str.pop_back();
cout<<str<<endl;
Perm2(str, 0, str.length()-1);
}
int main()
{
// vector<char> chars;
// int n;
// cin>>n;
// char ele;
// for(int i=0; i<n; i++)
// {
// cin>>ele;
// chars.push_back(ele);
// }
// // for(const char x:chars) cout<<x;
// Foo(chars);
string str;
// scanf("%s", str); https://blog.csdn.net/liu16659/article/details/86772657 不建议使用scanf输入string类型
cin>>str;
Foo2(str);
system("pause");
return 0;
}
B.快速幂
// B.快速幂
#include<bits/stdc++.h>
using namespace std;
const long long Mod = 1e8 + 7;
typedef long long ll;
ll Pow(ll base, ll power)
{
ll result = 1;
for(int i=1; i<=power; ++i)
{
result *= power;
result %= 1000; //每步结果提前进行取模
}
return result%1000;
}
// 快速幂
// 所以我们快速幂算法的核心思想就是每一步都把指数分成两半,
// 而相应的底数做平方运算。这样不仅能把非常大的指数给不断变小,
// 所需要执行的循环次数也变小,而最后表示的结果却一直不会变
ll fastPow(ll base, ll power)
{
ll result = 1;
while(power>0)
{
if(power%2 == 0)
{
base = base*base % Mod;
power /= 2;
}
else
{
power -= 1;
result = result*base % Mod;
base = base*base % Mod;
power /= 2;
}
}
return result;
}
ll myPow(int x)
{
ll result = 0;
for(int i=1; i<=x; ++i)
result += fastPow(i, i);
return (result+1)%Mod;
}
int main()
{
int x;
while(cin>>x)
{
cout<<myPow(x)<<endl;
}
system("pause");
return 0;
}
C.求第k小的数
// C.求第k小的数
#include<bits/stdc++.h>
using namespace std;
int Partition(int a[], int low, int high);
template<class Type>
int RandomizedPartition(Type a[], int p, int r);
template<class Type>
void RandomizedQuickSort(Type a[], int p, int r);
template<class Type>
Type RandomizedSelect(Type a[], int p, int r, int k);
int main()
{
// int n, k;
// cin>>n>>k;
// vector<int> vec;
// for(int i=0; i<n; ++i)
// {
// int num;
// scanf("%d", &num);
// vec.push_back(num);
// }
// sort(vec.begin(), vec.end());
// cout<<vec[k-1];
int a[100], n;
while(~scanf("%d", &n))
{
memset(a, 0, sizeof(a));
for(int i=0; i<n; i++) scanf("%d",&a[i]);
int k;
scanf("%d", &k);
cout<<RandomizedSelect(a, 0, n-1, k)<<endl;
}
system("pause");
return 0;
}
// 2.RandomizedSelect,平均时间复杂度O(n)
int Partition(int a[], int low, int high)
{
int key = a[low];
while(low<high)
{
while(low<high&&a[high]>key) --high;
a[low] = a[high];
while(low<high&&a[low]<=key) ++low;
a[high] = a[low];
}
a[low] = key;
return low;
}
template<class Type>
int RandomizedPartition(Type a[], int p, int r)
{
int i = rand()%(r-p+1) + p;
swap(a[i], a[p]);
return Partition(a, p, r);
}
// template<class Type>
// void RandomizedQuicksort(Type a[], int p, int r) //随机快排
// {
// if(p<r)
// {
// int q = RandomizedPartition(a, p, r);
// RandomizedQuicksort(a, p, q-1); //对左半段排序
// RandomizedQuicksort(a, q+1, r); //对右半段排序
// }
// }
template<class Type>
Type RandomizedSelect(Type a[], int p, int r, int k) //随机划分,选择
{
if(p == r) return a[p];
int loc = RandomizedPartition(a, p ,r);
int count = loc-p+1; //count为a[p:r]中的元素个数
if(k<=count) return RandomizedSelect(a, p, loc, k);
else return RandomizedSelect(a, loc+1, r, k-count);
}
D.内部收益率
// D.内部收益率
#include<bits/stdc++.h>
using namespace std;
int main()
{
int a[100], n;
while(scanf("%d", &n) && n)
{
for(int i=0; i<=n; i++) scanf("%d", a+i);
double x = -1.0, y=1e6, irr, npv;
for(int j=0; j<200; j++)
{
irr = (x+y)/2; //枚举irr的取值范围[-1.0, 1e6], 二分法逼近 (至于这个范围怎么来的,我就不清楚了.数学问题)
npv = 0;
for(int k=0; k<=n; k++)
npv += 1.0*a[k]/pow(1+irr, k);
if(fabs(npv)<1e-6) break; //小于一个阈值,认为就是方程的解
if(npv < 0) y = irr;
if(npv > 0) x = irr;
}
printf("%.2lf\n", irr);
memset(a, 0, sizeof(a)); //每次重置a数组
}
// cout<<9/2.25<<endl;
system("pause");
return 0;
}
E.跳台阶
// 跳台阶
#include<bits/stdc++.h>
using namespace std;
// f(x) = f(x-1) + f(x-2)
int climbStairsMemo(int n, vector<int>& memo)
{
if(memo[n]>0) return memo[n]; //记录数组
if(n==1 || n==2) memo[n] = n;
else memo[n] = climbStairsMemo(n-1, memo) + climbStairsMemo(n-2, memo);
return memo[n];
}
int climbStairs(int n) {
vector<int> memo(n+1, 0);
return climbStairsMemo(n, memo);
}
// 滚动数组 将空间复杂度由O(n)优化成O(1)
int climbStairs2(int n)
{
int p=0, q=0, r=1;
for(int i=1; i<=n; i++)
{
p = q;
q = r;
r = p+q;
}
return r;
}
int main()
{
int n;
cin>>n;
cout<<climbStairs2(n)%1000000007<<endl;
system("pause");
return 0;
}
2.Contest2445 - 毕老师算法实验二
传送门在这里
题目总览:
A.沙子的质量
// A.沙子的质量 OJ作业一D题
// 动态规划
#include<bits/stdc++.h>
using namespace std;
const int inf = 0x3f3f3f3f; //为什么用0x3f3f3f3f而不用0xffffff https://blog.csdn.net/jiange_zh/article/details/50198097
int Compute(int *nums, int n)
{
int Sum[n+1]={0};
int DP[n+1][n+1]; //之前用DP[1005][1005],导致栈空间溢出 https://blog.csdn.net/kangyupl/article/details/90723367
memset(DP, inf, sizeof(DP));
for(int i=1; i<=n; i++)
{
Sum[i] = Sum[i-1] + nums[i];
DP[i][i] = 0;
}
for(int Len=2; Len<=n; Len++)
for(int left=1; left<=n-Len+1; left++)
{
int right = left+Len-1;
for(int k=left; k<right; k++)
{
DP[left][right] = min(DP[left][k]+DP[k+1][right]+Sum[right]-Sum[left-1], DP[left][right]);
}
}
return DP[1][n];
}
int main()
{
int n;
cin>>n;
int nums[n+1];
nums[0] = 0;
for(int i=1; i<=n; ++i) cin>>nums[i];
cout<<Compute(nums, n)<<endl;
system("pause");
return 0;
}
B.最长公共子序列
// B.最长公共子序列 OJ作业一F题
// 动态规划
#include<bits/stdc++.h>
using namespace std;
int longestCommonSequence(string a, string b)
{
int M = a.size();
int N = b.size();
vector<vector<int>> DP(M+1, vector<int>(N+1, 0));
for(int i=1; i<=M; ++i)
{
for(int j=1; j<=N; ++j)
{
if(a[i-1]==b[j-1]) DP[i][j] = DP[i-1][j-1] + 1;
else DP[i][j] = max(DP[i-1][j], DP[i][j-1]);
}
}
return DP[M][N];
}
int main()
{
string a, b;
cin>>a>>b;
cout<<longestCommonSequence(a, b)<<endl;
system("pause");
return 0;
}
C.三角形的路径权
// C.三角形最小路径权
// Leetcode 125题
// 动态规划
#include<bits/stdc++.h>
using namespace std;
// 理解错误,直角三角形的情况.
int minimumTotal2(vector<vector<int>> &triangle)
{
int n = triangle.size();
vector<vector<int>> dp(n, vector<int>(n));
dp[0][0] = triangle[0][0];
dp[1][0] = triangle[1][0], dp[1][1] = triangle[0][0]+triangle[1][1];
if(n==2) return dp[1][1];
for(int i=2; i<n; i++)
{
dp[i][0] = dp[i-1][1] + triangle[i][0];
for(int j=1; j<=i-2; j++)
{
dp[i][j] = max(dp[i-1][j-1], dp[i-1][j+1]) + triangle[i][j];
}
dp[i][i] = dp[i-1][i-1] + triangle[i][i];
dp[i][i-1] = dp[i-1][i-2] + triangle[i][i-1];
}
cout<<endl<<endl<<"DP数组更新为:"<<endl;
for(const auto x:dp)
{
for(const int y:x) cout<<y<<" ";
cout<<endl;
}
return *max_element(dp[n-1].begin(), dp[n-1].end());
}
// 看成等腰三角形
int maximumTotal(vector<vector<int>> &triangle)
{
int n = triangle.size();
vector<vector<int>> dp(n, vector<int>(n,0));
dp[0][0] = triangle[0][0];
for(int i=1; i<n; i++)
{
dp[i][0] = dp[i-1][0] + triangle[i][0];
for(int j=1; j<n-1; j++)
{
dp[i][j] = max(dp[i-1][j-1], dp[i-1][j]) + triangle[i][j];
}
dp[i][i] = dp[i-1][i-1] + triangle[i][i];
}
return *max_element(dp[n-1].begin(), dp[n-1].end());
}
int main()
{
int n;
cin>>n;
vector<vector<int>> triangle(n, vector<int>(n));
for(int i=0; i<n; i++)
{
for(int j=0; j<=i; j++)
cin>>triangle[i][j];
}
cout<<maximumTotal(triangle)<<endl;
system("pause");
return 0;
}
D.跳跃游戏Ⅱ
// D.跳跃游戏Ⅱ
// LeetCode第45题
// 贪心算法
#include<bits/stdc++.h>
using namespace std;
// 思想就一句话:每次在上次能跳到的范围(end)内选择一个能跳的最远的位置(也就是能跳到max_far位置的点)作为下次的起跳点 !
int Jump(vector<int> &nums)
{
int n = nums.size();
int max_far = 0; //目前能够跳到的最远位置
int step = 0;
int end = 0; //上次跳跃可到达的范围右边界
for(int i=0; i<n-1; i++) //<n-1,最后一个元素不用遍历.
{
max_far = max(i+nums[i], max_far);
if(i == end)
{
end = max_far;
step++;
}
}
return step;
}
int main()
{
int n;
cin>>n;
vector<int> nums(n);
for(int i=0; i<n; i++) cin>>nums[i];
cout<<Jump(nums)<<endl;
system("pause");
return 0;
}
E.字母排序
// E.字母排序
// 最长不降子序列
#include<bits/stdc++.h>
using namespace std;
// 1.LIS ---> LCS 最长递增子序列(排序+LCS)
// const int N = 1010;
// int DP[N][N];
// int DIR[N][N];
// int LCS_Length(string a, string b)
// {
// int m = a.size();
// int n = b.size();
// for(int i=1; i<=m; i++)
// {
// for(int j=1; j<=n; j++)
// {
// if(a[i-1] == b[j-1])
// {
// DP[i][j] = DP[i-1][j-1] + 1;
// DIR[i][j] = 1;
// }
// else if(DP[i-1][j] > DP[i][j-1])
// {
// DP[i][j] = DP[i-1][j];
// DIR[i][j] = 2;
// }
// else
// {
// DP[i][j] = DP[i][j-1];
// DIR[i][j] = 3;
// }
// }
// }
// return DP[m][n];
// }
// void LCS(string a, int i, int j)
// {
// if(i==0 || j==0) return;
// if(DIR[i][j] == 1)
// {
// LCS(a, i-1, j-1);
// cout<<a[i-1];
// }
// else if(DIR[i][j] == 2) LCS(a, i-1, j);
// else if(DIR[i][j] == 3) LCS(a, i, j-1);
// }
// string RD(string b, int &add) //去重函数 hhh变为h
// {
// bool Flag[b.size()] = {false};
// for(int i=1; i<b.size(); i++)
// {
// if(b[i] == b[i-1])
// {
// add++;
// Flag[i] = true;
// }
// }
// for(int i=0; i<b.size(); i++)
// {
// if(Flag[i] == 1) b[i] = '.';
// }
// // cout<<b<<endl;
// b.erase(std::remove(b.begin(), b.end(), '.'), b.end()); //去重操作
// return b;
// }
// int LIS_Length(string a, string b)
// {
// return LCS_Length(a, b);
// }
// int main()
// {
// string a, str;
// cin>>a;
// cin.ignore(); //空格
// getline(cin, str);
// str += ' ';
// string b;
// int Start_pos = 0;
// int add = 0;
// for(int i=0; i<str.size(); i++)
// {
// if(str[i] == ' ')
// {
// // cout<<"Flag"<<i<<endl;
// b = str.substr(Start_pos, i-Start_pos);
// // cout<<b<<endl;
// RD(b, add);
// cout<<LIS_Length(a, b)+add;
// Start_pos = i+1;
// add = 0;
// }
// }
// // string test;
// // cin>>test;
// // int add = 0;
// // cout<<RD(test, add)<<" "<<add<<endl;
// // cout<<test<<endl;
// system("pause");
// return 0;
// }
// 2.DP
// O(n^2)
// int LengthOfLIS(vector<int> &nums)
// {
// int n = nums.size();
// if(n==0) return 0;
// vector<int> dp(n, 1);
// for(int i=0; i<n; i++)
// {
// for(int j=0; j<i; j++)
// {
// if(nums[i] > nums[j])
// {
// dp[i] = max(dp[j]+1, dp[i]);
// }
// }
// }
// return *max_element(dp.begin(), dp.end());
// }
// int main()
// {
// int n;
// while(scanf("%d", &n) && n)
// {
// vector<int> nums(n);
// for(int i=0; i<n; i++) scanf("%d", &nums[i]);
// cout<<LengthOfLIS(nums)<<endl;
// }
// system("pause");
// return 0;
// }
// 3.贪心 + 二分查找
// 维护一个一维数组B,并且这个数组是动态扩展的,初始大小为1,
//B[i]表示最长上升子序列长度是i的所有子串中末尾最小的那个数,根据这个数字,我们可以比较知道,
//只要当前考察的这个数比B[i]大,那么当前这个数一定能通过B[i]构成一个长度为i+1的上升子序列。
//如果当前考察的数并没有数组尾部的B[i]大,那么我们选择在B数组中找到第一个大于当前考察数的元素,并且更换.
// 正确!!!
int BinarySearch(vector<int> &nums, int l, int r, int target) //在nums数组中找到第一个大于target的数,然后更新它
{
if(l == r) return l;
int mid;
while(l <= r)
{
mid = (l+r)/2;
if(nums[mid] == target) return mid; //return mid!
else if(nums[mid] > target) r = mid-1;
else l = mid+1;
}
return l;
}
int LengthOfLIS(vector<int> &nums)
{
int n = nums.size();
vector<int> B(n+1);
B[0] = 0;
B[1] = nums[0];
int len = 1; //表示B数组的长度
for(int i=1; i<n; i++)
{
if(nums[i] > B[len])
{
B[++len] = nums[i];
}
else if(nums[i] < B[len])
{
int pos = BinarySearch(B, 1, len, nums[i]); //在B数组中找到第一个大于nums[i]的元素位置
cout<<pos<<" "<<i<<" "<<nums[i]<<endl;
B[pos] = nums[i];
}
}
for(const int x:B) cout<<x<<" ";
cout<<endl;
return len;
}
// 力扣! https://leetcode-cn.com/problems/longest-increasing-subsequence/solution/zui-chang-shang-sheng-zi-xu-lie-by-leetcode-soluti/
// 考虑一个简单的贪心,如果我们要使上升子序列尽可能的长,则我们需要让序列上升得尽可能慢,因此我们希望每次在上升子序列最后加上的那个数尽可能的小。
// 我们依次遍历数组 nums 中的每个元素,并更新数组 d 和 len 的值。如果nums[j] > d[len] 则更新 len = len + 1
// 否则在 d[1...len] 中 找到 d[i-1] < nums[j] < d[i]的pos值,然后更新d[i] = nums[j]
int lengthOfLIS(vector<int> &nums)
{
int len = 1, n = int(nums.size());
if(n == 0) return 0;
vector<int> d(n+1, 0);
d[len] = nums[0];
for(int i=1; i<n; ++i)
{
if(nums[i] > d[len])
d[++len] = nums[i];
else
{
int l = 1, r = len, pos = 0; //如果找不到说明所有的数都比nums[i]大,此时要更新d[1]
while(l <= r)
{
int mid = (l+r) >> 1;
if(d[mid] < nums[i])
{
pos = mid;
l = mid+1;
}
else r = mid-1;
}
d[pos+1] = nums[i];
}
}
return len;
}
int main()
{
int t;
cin>>t;
while(t--)
{
int n;
cin>>n;
vector<int> nums(n);
for(int i=0; i<n; i++)
cin>>nums[i];
cout<<LengthOfLIS(nums)<<endl;
}
system("pause");
return 0;
}
3.Contest2453 - 毕老师算法实验三
传送门在这里
题目总览:
A.Homework
// D.Homework
// 正确!
#include<bits/stdc++.h>
using namespace std;
bool cmp(pair<double, double> a, pair<double, double> b)
{
return a.second/a.first > b.second/b.first;
}
int main()
{
int M, N;
while(scanf("%d%d", &M, &N) && (M && N))
{
vector<pair<double, double>> vec;
double time, value;
for(int i=0; i<M; ++i)
{
scanf("%lf%lf", &time, &value);
vec.push_back(pair<double, double>(time, value));
}
sort(vec.begin(), vec.end(), cmp);
double TimeTotal = N;
double ValueTotal = 0; //double类型,如果写为int类型答案错误
for(const auto x:vec) cout<<"("<<x.first<<","<<x.second<<")"<<endl;
for(const pair<double, double> x:vec)
{
if(TimeTotal-x.first >= 0)
{
cout<<"Flag1"<<endl;
ValueTotal += x.second;
TimeTotal -= x.first;
}
else
{
ValueTotal += TimeTotal * x.second/x.first;
break;
}
}
printf("%.2lf\n", ValueTotal);
}
system("pause");
return 0;
}
B.区间包含问题
// E.区间包含问题
// 贪心算法 类似于活动安排问题
#include<bits/stdc++.h>
using namespace std;
const int maxn = 10010;
struct Node
{
int left, right;
}node[maxn];
bool cmp(Node a, Node b)
{
return a.right < b.right;
}
int main()
{
int n, m;
scanf("%d %d", &n, &m);
for(int i=0; i<n; ++i)
{
scanf("%d %d", &node[i].left, &node[i].right);
// node[i].right++;
}
sort(node, node+n, cmp);
int l, r;
for(int i=0; i<m; ++i)
{
scanf("%d %d", &l, &r);
int pos = l, ans = 0;
for(int j=0; j<n; ++j)
{
if(node[j].left>=pos && node[j].right<=r)
{
cout<<l<<" "<<r<<endl;
cout<<j<<" "<<node[j].left<<" "<<node[j].right<<endl;
ans++;
pos = node[j].right;
}
}
printf("%d\n", ans);
}
system("pause");
return 0;
}
C.最长子序列
// F.最长子序列(最大子段和)
#include<bits/stdc++.h>
using namespace std;
// 1.递归分治法
// f(i) = max(f(i-1)+nums[i], nums[i]) 考虑f(i-1)带来的是正能量还是负能量
// f(i) 代表以第 i 个数结尾的「连续子数组的最大和」,那么很显然我们要求的答案就是:
// max(0-i-1){f[i]}
int maxSubArray(vector<int> &nums)
{
int n = nums.size();
if(n==0) return {};
if(n==1) return nums[0];
vector<int> f(n);
f[0] = nums[0];
for(int i=1; i<n; ++i)
{
f[i] = max(f[i-1]+nums[i], nums[i]);
}
for(const int x:f) cout<<x<<" ";
cout<<endl;
return *max_element(f.begin(), f.end()); //记住不是返回f[n-1]
}
int maxSubArray2(vector<int> &nums)
{
int n = nums.size();
if(n==0) return {};
int pre = 0, maxAns = nums[0];
for(const int x:nums)
{
pre = max(pre+x, x); //pre记录当前x前面的连续子数组的最大和,即f[i-1],不断更新. 类似于滚动数组
maxAns = max(maxAns, pre);
}
return maxAns;
}
int main()
{
int n;
while(~scanf("%d", &n))
{
vector<int> nums(n);
for(int i=0; i<n; ++i) scanf("%d", &nums[i]);
cout<<maxSubArray(nums)<<endl;
}
system("pause");
return 0;
}
D.三值排序
// D.三值排序
#include<bits/stdc++.h>
using namespace std;
int ThreeSort(vector<int> &nums)
{
int n = nums.size();
int a=0, b=0, c=0;
for(int i=0; i<n; ++i)
{
if(nums[i]==1) a++;
else if(nums[i]==2) b++;
else if(nums[i]==3) c++;
}
int dif[4][4] = {0};
for(int i=0; i<a; i++)
if(nums[i] != 1) dif[1][nums[i]]++;
for(int i=a; i<a+b; i++)
if(nums[i] != 2) dif[2][nums[i]]++;
for(int i=a+b; i<n; i++)
if(nums[i] != 3) dif[3][nums[i]]++;
int ans = 0, sum = 0;
for(int i=1; i<4; i++)
{
for(int j=i+1; j<4; j++)
{
if(dif[i][j] <= dif[j][i])
{
ans += dif[i][j];
sum += dif[j][i] - dif[i][j];
}
else
{
ans += dif[j][i];
sum += dif[i][j] - dif[j][i];
}
}
}
ans = ans + sum/3*2; //三个数字都不在自己该在的位置,但是只需要两步就能变得有序:213变为123只需两步 312 132等等同样
return ans;
}
int main()
{
int n;
cin>>n;
vector<int> nums(n);
int a=0, b=0, c=0;
for(int i=0; i<n; ++i)
scanf("%d", &nums[i]);
cout<<ThreeSort(nums)<<endl;
system("pause");
return 0;
}
E.法师康的工人
// E.法师康的工人
// 这一题有点问题,我好像没改过来
#include<bits/stdc++.h>
using namespace std;
bool cmp(pair<int, int> a, pair<int, int> b)
{
return a.second < b.second;
}
int main()
{
int n;
cin>>n;
vector<pair<int, int>> vec;
int left, right;
for(int i=0; i<n; ++i)
{
scanf("%d%d", &left, &right);
vec.push_back(pair<int, int>(left, right));
}
sort(vec.begin(), vec.end(), cmp);
int left_border = vec[0].first;
int right_border = vec[0].second;
int max_ContinuousLength = right_border-left_border;
int max_IntervalLength = 0;
for(int i=1; i<n; ++i)
{
if(vec[i].first <= right_border)
{
right_border = max(right_border, vec[i].second);
left_border = min(left_border, vec[i].first);
}
else
{
max_ContinuousLength = max(max_ContinuousLength, right_border-left_border);
max_IntervalLength = max(max_IntervalLength, vec[i].first-right_border);
left_border = vec[i].first; //出现间隔,重置边界
right_border = vec[i].second;
}
}
max_ContinuousLength = max(max_ContinuousLength, right_border-left_border);
// 防止 2 (100 500) (400 900)这种没有间断的情况出现,直接跳出循环的话
cout<<max_ContinuousLength<<" "<<max_IntervalLength<<endl;
system("pause");
return 0;
}
// 10
// 2 3
// 4 5
// 6 7
// 8 9
// 10 11
// 12 13
// 14 15
// 16 17
// 18 19
// 1 20
// 19 1
// 请按任意键继续. . .
// 正确答案:19 0 错误的原因?咋改
4.Contest2462 - 毕老师算法实验四
传送门在这里
题目总览:
A.凯撒加密法
// A.żČöĂÜÂë
#include<bits/stdc++.h>
using namespace std;
string CaesarCipher(string ciphertext, int n)
{
int length = ciphertext.size();
for(int i=0; i<length; ++i)
{
if(isupper(ciphertext[i]))
ciphertext[i] = 'A' + (ciphertext[i]-'A'-n+26)%26;
else if(islower(ciphertext[i]))
ciphertext[i] = 'a' + (ciphertext[i]-'a'-n+26)%26;
}
return ciphertext;
}
int main()
{
int T;
scanf("%d", &T);
// for(int i=0; i<T; ++i)
// {
// string ciphertext;
// // cin>>ciphertext;
// cin.ignore();
// getline(cin, ciphertext);
// int k;
// cin>>k;
// k = k%26;
// cout<<CaesarCipher(ciphertext, k)<<endl;
// }
string str[T];
int change[T];
for(int i=0; i<T; ++i)
{
cin>>str[i];
cin>>change[i];
change[i] %= 26;
}
for(int i=0; i<T; i++)
{
cout<<CaesarCipher(str[i], change[i])<<endl;
}
system("pause");
return 0;
}
B.维吉尼亚密码
// B.¸ĽźŞÄáŃÇĂÜÂë
#include<bits/stdc++.h>
using namespace std;
string fill(string key, string plainText)
{
int len1 = key.size();
int len2 = plainText.size();
if(len1 < len2)
{
int num = len2 - len1;
string temp = key;
for(int i=0; i<num; ++i)
{
key += temp[i%len1];
}
}
for(int i=0; i<len2; ++i)
{
if(islower(key[i]))
key[i] -= 32;
}
return key;
}
int main()
{
string key, cipherText;
cin>>key>>cipherText;
key = fill(key, cipherText);
// cout<<key<<endl;
int len = cipherText.size();
string plainText;
int change;
for(int i=0; i<len; ++i)
{
change = key[i] - 'A';
// cout<<i<<": "<<change<<endl;
if(isupper(cipherText[i]))
plainText.push_back('A' + (cipherText[i]-'A'- change + 26)%26);
else
plainText.push_back('a' + (cipherText[i]-'a'- change + 26)%26);
}
cout<<plainText<<endl;
system("pause");
return 0;
}
C.简单的密码
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
int f[35] = {0, 0, 0, 1};
for(int i=4; i<=30; ++i)
f[i] = f[i-1]*2 + pow(2, i-4) - f[i-4];
while(cin>>n && n>=1 && n<=30)
cout<<f[n]<<endl;
system("pause");
return 0;
}
D.有趣的素数
// 带佬代码
#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
int n,ans,last;
bool visited[32];
bool isPrime[40]={0,0,1,1,0,1,0,1,0,0,0,1,0,1,0,0,0,1,0,1,0,0,0,1,0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,0};
void pc(int cur)
{
if(cur == n && isPrime[1+last])
{
ans++;
return;
}
for(int i = 2; i <= n; i++)
{
if(!visited[i] && isPrime[last+i])
{
int t = last;
last = i;
visited[i] = true;
pc(cur+1);
visited[i] = false;
last = t;
}
}
}
int main()
{
while(~scanf("%d",&n))
{
memset(visited,0,sizeof(visited));
ans = 0;
last = 1;
pc(1);
printf("%d\n",ans);
}
return 0;
}
E.数据加密
// E.数据加密
#include<bits/stdc++.h>
using namespace std;
string CipherCompute(string PlainText)
{
int n = PlainText.size();
string ans;
if(n==0) return {};
if(n==1) return PlainText;
int left = 0, right = n-1;
while(n>0)
{
if(PlainText[left] < PlainText[right])
{
ans += PlainText[left];
left++;
n--;
}
else if(PlainText[left] > PlainText[right])
{
ans += PlainText[right];
right--;
n--;
}
else
{
int temp_left = left+1, temp_right = right-1;
while(temp_left<n && temp_right>=0 && temp_left <= temp_right && PlainText[temp_left] == PlainText[temp_right])
{
temp_left++;
temp_right--;
}
if(PlainText[temp_left]>PlainText[temp_right])
{
ans += PlainText[right];
right--;
n--;
}
else
{
ans += PlainText[left];
left++;
n--;
}
}
}
return ans;
}
int main()
{
int t;
cin>>t;
while(t--)
{
int n;
cin>>n;
string PlainText;
cin>>PlainText;
string Cipher = CipherCompute(PlainText);
cout<<Cipher<<endl;
}
system("pause");
return 0;
}
// 带佬代码
#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
int main()
{
int n;
char str[2005],ans[2005];
while(~scanf("%d",&n))
{
scanf("%s",str);
int i = 0,j = n-1;
while(i <= j)
{
bool flag = false;
for(int k = 0; i+k < j-k; k++)
{
if(str[i+k] < str[j-k])
{
flag = true;
break;
}
if(str[i+k] > str[j-k]) break;
}
if(flag) printf("%c",str[i++]);
else printf("%c",str[j--]);
}
printf("\n");
}
return 0;
}
(~ ̄▽ ̄)~
如果大家觉得本篇文章对自己有所帮助的话,不妨去我的个人博客---乔治的编程小屋逛逛吧.
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。