备注:
一定要注意到,如果不是long long就会出错,这是由于
代码:
#include<bits/stdc++.h>
using namespace std;
bool is_prime(long long n){
if(n==2||n==3)
return true;
if(n%2==0 && n!=2)
return false;
for(int i=3;i<=(int)sqrt(n);i=i+2){
if(n%i==0)
return false;
}
return true;
}
int main(){
int n;
cin>>n;
long long h=2;
long long N=1;
while(n>=0){
for(int i=h; ;i++){
if(is_prime(i)){
h=i+1;
N=N*i; //每次都是乘正常的i 获得最正常的累加,最后判断是+1 i记录正常的。
break;
}
}
n--;
}
if(is_prime(N+1))
cout<<N+1<<" is a prime"<<endl;
else
cout<<N+1<<" is not a prime"<<endl;
}
vivo提前批第二题,01背包问题
输入:
4
1,3,4
15,20,30
//第一行是背包最大容量,第二行是物体重量,第三行是物体的价值,输出这个背包的最大能装的价值
思路:
今天有空就吧这个输入练习了下,顺便回顾了下01背包问题,在这里我使用了stringstream,非常方便哈哈。对逗号,分号或者空格我都能处理了。不用使用之前的helper方法,多行的时候,我只需要循环个geiline就行了,然后stringstream读取这个元素,然后在while中逐个输出就行了。挺好,如果需要矩阵,我矩阵也能操作挺好挺好
注意到01背包搜索方向是左上角,我第一行已经填完了,第二行操作的时候就没事了,初始化最大价值0,数组0,然后第一行就是1个物体的时候最大价值我们可以直到,以及背包容量为0时候的最大价值
#include<iostream>
#include<vector>
#include<algorithm>
#include <sstream>
#include<string>
#include<cstring>
using namespace std;
int main(){
int n;
string s1,s2;
string temp;
vector<int>w,v;
cin>>n;
cin.get();
getline(cin,s1);
getline(cin,s2);
stringstream ss1;
ss1<<s1;
stringstream ss2;
ss2<<s2;
while(getline(ss1,temp,',')){
w.push_back(stoi(temp));
}
while(getline(ss2,temp,',')){
v.push_back(stoi(temp));
}
// 结束初始化 进行背包问题
int maxn=0;
vector<vector<int> >dp(w.size(),vector<int>(n+1,0)) ;
for(int j=w[0];j<=n;j++)
dp[0][j]=v[0];
//结束初始化进入循环
for(int i=1; i<w.size();i++){
for(int j=1; j<=n;j++){
if(j<w[i])
dp[i][j]=dp[i-1][j];
else{
dp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i]]+v[i]);
}
}
}
cout<<dp[w.size()-1][n];
return 0;
}
下面贴上滚动数组的方法,节省了空间复杂度:
#include<iostream>
#include<vector>
#include<algorithm>
#include <sstream>
#include<string>
#include<cstring>
using namespace std;
int main(){
int n;
string s1,s2;
string temp;
vector<int>w,v;
cin>>n;
cin.get();
getline(cin,s1);
getline(cin,s2);
stringstream ss1;
ss1<<s1;
stringstream ss2;
ss2<<s2;
while(getline(ss1,temp,',')){
w.push_back(stoi(temp));
}
while(getline(ss2,temp,',')){
v.push_back(stoi(temp));
}
// 结束初始化 进行背包问题
int maxn=0;
vector<int>dp(n+1,0) ;
dp[0]=0; //这个可以不用写
//结束初始化进入循环
for(int i=0; i<w.size();i++){ //i从0开始了,因为没有初始化第一行呢!只是初始化了列。
for(int j=n; j>=w[i];j--){
dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
}
}
cout<<dp[n];
return 0;
}
编程题:开根号
题目:
代码:
//注意审题:不用任何数学库函数,所以我们只用加减乘除
#include <iostream>
using namespace std;
//二分搜索求开n次方
double epr = 10E-14;
double Mysqrt(double m, int n)
{
double left = 0;
double right = m;
double mid = left + (right - left) / 2;
double last;//保存上一次运算的结果
double temp;
while ((right-left)>epr){ //当搜索的区间很小的时候,说明已经无限接近那个值了。 这个精度是自己选的。m除以mid n-1次
temp = m;
for (int i = 0; i<n-1; i++)
temp = temp / mid;
//二分
if (mid>temp) //这说明mid的n次放比m要大了,mid减少一点吧
right = mid;
else
left = mid;
//记录、更新
last = mid;
mid = left + (right - left) / 2;
}
return mid;
}
int main()
{
double m;
int n;
while (cin >> m >> n)
{
cout.precision(13); //不算逗号,从第一位有效数字开始算起来的 从题目知道这个数字比2要小,那肯定就是13位了/
cout << Mysqrt(m, n);
}
}