题目描述
有两个用字符串表示的非常大的大整数,算出他们的乘积,也是用字符串表示。不能用系统自带的大整数类型。
输入描述:
空格分隔的两个字符串,代表输入的两个大整数
输出描述:
输入的乘积,用字符串表示
示例1
输入 72106547548473106236 982161082972751393
输出 70820244829634538040848656466105986748
思路:
我一开始写的很复杂而且没有头绪,下面是别人的解法
使用一个string全为0的string作为结果记录,去更新这个string
#include
#include
using namespace std;
string getMutiply(string s1,string s2){
if(s1.empty() || s2.empty()) return "";
string res(s1.size()+s2.size(),'0');
for(int i = s2.size()-1;i >= 0;i--){
int carry = 0,cur;
for(int j = s1.size()-1;j >= 0;j--){
cur = res[i+j+1]-'0' + (s1[j]-'0')*(s2[i]-'0') + carry;
res[i+j+1] = cur%10+'0';
carry = cur / 10;
}
res[i] += carry;
}
int idx = 0;
while(idx < res.size() && res[idx] == '0') idx++;
return idx == res.size()? "0":res.substr(idx);
}
int main(){
string s1,s2;
cin >> s1 >> s2;
string res = getMutiply(s1,s2);
cout << res << endl;
return 0;
}
A string s is LUCKY if and only if the number of different characters in s is a fibonacci number. Given a string consisting of only lower case letters , output all its lucky non-empty substrings in lexicographical order. Same substrings should be printed once.
a string consisting no more than 100 lower case letters.
output the lucky substrings in lexicographical order.one per line. Same substrings should be printed once.
示例1
aabcd
a
aa
aab
aabc
ab
abc
b
bc
bcd
c
cd
d
思路:我一直没法AC,后来发现原因是:
(1)这个不能有重复的输出,所以我取了个set做,否则aab会有两次a输出。
(2)字典序输出,必须sort一下
题目这么看的话其实挺智障的。。。
#include
#include
#include
#include
#include
using namespace std;
int main(){
string s;
int fib[7] = {1,2,3,5,8,13,21};
while(cin >> s){
set res;
for(int i = 0;i < s.size();i++){
set word_map;
int k = 0;
for(int j = i;j < s.size();j++){
word_map.insert(s[j]);
if(word_map.size() > fib[k] && k < 6) k++;
if(word_map.size() == fib[k]) res.insert(s.substr(i,j-i+1));
}
}
for(auto &str:res) cout << str << endl;
}
}
开发一个简单错误记录功能小模块,能够记录出错的代码所在的文件名称和行号。
处理:
1.记录最多8条错误记录,对相同的错误记录(即文件名称和行号完全匹配)只记录一条,错误计数增加;(文件所在的目录不同,文件名和行号相同也要合并)
2.超过16个字符的文件名称,只记录文件的最后有效16个字符;(如果文件名不同,而只是文件名的后16个字符和行号相同,也不要合并)
3.输入的文件可能带路径,记录文件名称不能带路径
一行或多行字符串。每行包括带路径文件名称,行号,以空格隔开。
文件路径为windows格式
如:E:\V1R2\product\fpgadrive.c 1325
将所有的记录统计并将结果输出,格式:文件名代码行数数目,一个空格隔开,如: fpgadrive.c 1325 1
结果根据数目从多到少排序,数目相同的情况下,按照输入第一次出现顺序排序。
如果超过8条记录,则只输出前8条记录.
如果文件名的长度超过16个字符,则只输出后16个字符
示例1
E:\V1R2\product\fpgadrive.c 1325
fpgadrive.c 1325 1
思路:这题看着简单,写起来内心一万个卧槽还写不对。。。我写输入输出真的太弱了,后期注意看一下
python:
import sys
files = []
count = []
while True:
try:
a = input()
file_line = a.split('\\')[-1]
if file_line not in files:
files.append(file_line)
count.append(1)
else:
idx = files.index(file_line)
count[idx] += 1
except:
break
lenth = min(len(files),8)
sort_count = sorted(count,reverse=True)
for cnt in sort_count[:lenth]:
idx = count.index(cnt)
result = files[idx]
result = result.split()
if len(result[0])>16:
print(result[0][-16:]+' '+result[1]+' '+str(cnt))
else:
print(result[0]+' '+result[1]+' '+str(cnt))
del count[idx]
del files[idx]
有 n 个学生站成一排,每个学生有一个能力值,牛牛想从这 n 个学生中按照顺序选取 k 名学生,要求相邻两个学生的位置编号的差不超过 d,使得这 k 个学生的能力值的乘积最大,你能返回最大的乘积吗?
每个输入包含 1 个测试用例。每个测试数据的第一行包含一个整数 n (1 <= n <= 50),表示学生的个数,接下来的一行,包含 n 个整数,按顺序表示每个学生的能力值 ai(-50 <= ai <= 50)。接下来的一行包含两个整数,k 和 d (1 <= k <= 10, 1 <= d <= 50)。
输出一行表示最大的乘积。
示例1
3
7 4 7
2 50
49
思路:这题其实是LeetCode原题的变型,思路也差不多,一个难点就是输入有正有负,需要维护一个正数最大值和一个负数最小值
#include
#include
#include
using namespace std;
long long maxProduct(vector stu,int n,int k,int d){
long long max_res = 1;
vector> max_dp(k,vector(n,0));
vector> min_dp(k,vector(n,0));
for(int i = 0;i < n;i++){
if(stu[i] == 0) continue;
max_dp[0][i] = stu[i];
min_dp[0][i] = stu[i];
for(int j = 1;j < k;j++){
long long max_pre = 0,min_pre = 0;
for(int m = i-1;m >= 0 && m >= i-d;m--){
max_pre = max(max_pre,max_dp[j-1][m]);
min_pre = min(min_pre,min_dp[j-1][m]);
}
max_dp[j][i] = max(max_pre * stu[i],min_pre * stu[i]);
min_dp[j][i] = min(max_pre * stu[i],min_pre * stu[i]);
}
max_res = max(max_res, max_dp[k-1][i]);
}
return max_res;
}
int main(){
int n,k,d;
while(cin >> n){
vector stu(n);
for(int i = 0;i < n;i++) cin >> stu[i];
cin >> k >> d;
long long res = maxProduct(stu,n,k,d);
cout << res << endl;
}
}
牛牛和 15 个朋友来玩打土豪分田地的游戏,牛牛决定让你来分田地,地主的田地可以看成是一个矩形,每个位置有一个价值。分割田地的方法是横竖各切三刀,分成 16 份,作为领导干部,牛牛总是会选择其中总价值最小的一份田地, 作为牛牛最好的朋友,你希望牛牛取得的田地的价值和尽可能大,你知道这个值最大可以是多少吗?
每个输入包含 1 个测试用例。每个测试用例的第一行包含两个整数 n 和 m(1 <= n, m <= 75),表示田地的大小,接下来的 n 行,每行包含 m 个 0-9 之间的数字,表示每块位置的价值。
输出一行表示牛牛所能取得的最大的价值。
示例1
4 4 3332 3233 3332 2323
2
题意:即找到最小值的最大值
思路:这题我开始以为是dp,结果无处下手,这是一道很巧妙的贪心+二分查找。
横竖各三刀将一个矩阵分为16部分,每部分的value即为这一部分包含的所有数字之和。
我们要做的就是想一种切法,使得这16部分中value最小的那个尽可能的大。
首先很显然,每一个部分的value在0-sum之间,sum是指整个矩阵所有数字之和,
这样最终的结果一定是[0, sum]中的某一个整数。
这里稍微逆向思考一下,既然不容易直接求结果,可不可以我猜一个值k
然后判断能不能通过某种切法使最小的那一块value>=k,也就是说,使16块的value都能大于等于k,
如果可以的话,我们就可以对[0, sum]这个区间进行二分查找。
二分的复杂度是log(sum).
接下来是重点:对于一个值,怎么判断能不能横竖切三刀,使16块的value都大于等于k呢
二分答案,判断可行性时暴力枚举三列的情况,然后横着贪心地扫一遍,
每当四列都满足的时候就砍一刀,满足四次即可
#include
#include
using namespace std;
//记录坐标点(i,j)之前的所有元素(包括坐标点(i,j)在内)之和
vector> get_sum(vector> &nums,int m,int n){
vector> sums(m+1,vector(n+1,0));
for(int i = 1;i <= m;++i){
for(int j = 1;j <= n;++j){
sums[i][j] = sums[i-1][j] + sums[i][j-1] - sums[i-1][j-1] + nums[i-1][j-1];
}
}
return sums;
}
//计算(x1,y1)到(x2,y2)之间的面积, x1,y1不包含
int get_state(vector> &sums,int x1,int y1,int x2,int y2){
return sums[x2][y2]+sums[x1][y1]-sums[x1][y2]-sums[x2][y1];
}
//把矩阵(土地)a[n][m]分割成4块,并且满足条件:各个块的值都不小于k;
bool isValid(vector> &sums,int m, int n, int target){
for(int i = 1;i <= m-3;i++){
for(int j = i+1;j <= m-2;j++){
for(int k = j+1;k <= m;k++){
int y1 = 0,cnt = 0;
for(int y2 = y1+1;y2 <= n;y2++){
int s1 = get_state(sums,0,y1,i,y2);
int s2 = get_state(sums,i,y1,j,y2);
int s3 = get_state(sums,j,y1,k,y2);
int s4 = get_state(sums,k,y1,m,y2);
// 四列都满足时砍一刀,即y1 = y2操作
if(s1 >= target && s2 >= target && s3 >= target && s4 >= target){
cnt++;
y1 = y2;
}
if(cnt >= 4) return true;
}
}
}
}
return false;
}
int main(){
int m,n;
string s;
while(cin >> m >> n){
vector> nums(m,vector(n));
for(int i = 0;i < m;++i){
// 注意这里的输入没有空格,所以取到一个string上再进行操作!!!
cin >> s;
for(int j = 0;j < n;++j){
nums[i][j] = s[j]-'0';
}
}
vector> sums = get_sum(nums,m,n);
// 二分法
int i = 0,j = sums[m][n],mid,ans = 0;
while(i <= j){
mid = (i+j)/2;
if(isValid(sums,m,n,mid)){
i = mid+1;
ans = mid;
}
else j = mid-1;
}
cout << ans << endl;
}
}