赞
踩
算法分析与设计 题目解答。题目在http://47.99.179.148
#include <iostream> using namespace std; //堆排序用数组存的方式 void minHeapSort(int a[], int current, int high){ //current是当下需要调整的节点,high为数组边界 int i = current; int j = i*2; while(j <= high){ if(a[j+1] < a[j] && j+1 <= high){//先是同层级比较 j = j + 1; } if(a[j] < a[i]){//若儿子比父节点小,则交换 swap(a[i],a[j]); i = j; j = 2*i; } else{//否则跳出循环,不动 break; } } } int main() { int n; cin >> n; int q[n][1000]; unsigned char c; //输入 c = getchar(); for(int i=0; i<n; i++){ int j = 0; while((c=getchar()) != '\n'){ if(c != ' '){ ungetc(c,stdin);//如果c不是空格要把c还回到流中 cin >> q[i][j++]; } } } //应用堆排序 for (int i = 0; i < n; ++i) { for (int j = q[i][0]/2; j >= 1 ; j--) {//自下向上,自右向左调整顺序 minHeapSort(q[i],j,q[i][0]); } } //输出 for(int i=0; i<n; i++){ for(int j=1; j<=q[i][0]; j++){ cout << q[i][j] << " "; } cout << endl; } return 0; }
#include <iostream> #include <algorithm> #include <cmath> using namespace std; int M,N; struct Point{ int x; int y; }; Point p[50001]; //输入函数 void input(){ scanf("%d",&N); for(int i = 0; i < N; i++){ Point point{}; scanf("%d %d",&point.x,&point.y); p[i] = point; } } //对点排序,先按照横坐标排序,横坐标相同就按照纵坐标排序 bool cmp(const Point& p1,const Point& p2){ return p1.x == p2.x ? p1.y < p2.y : p1.x < p2.x; } //内联函数获取两点间距 inline double dis(const Point& p1, const Point& p2){ return sqrt((p1.x-p2.x)*(p1.x-p2.x) + (p1.y-p2.y)*(p1.y-p2.y)); } //求解最近点对 double divide(int left, int right, Point* pPoint){ Point point[50001]; if(left == right) return 0; //分治 int mid = (left+right)/2; Point p1{}; p1 = pPoint[mid]; //求解左边点集合和右边点集的最小距离,并再取最小 double d = min(divide(1, mid, pPoint), divide(mid + 1, right, pPoint)); int i = 1, j = mid+1, k = 0; //将左右两边的点根据横坐标再纵坐标排序合并入临时点数组中 while (i <= mid && j <= right){ if(pPoint[i].y < pPoint[j].y) point[k++] = pPoint[i++]; else point[k++] = pPoint[j++]; } while (i <= mid){ point[k++] = pPoint[i++]; } while (j <= right){ point[k++] = pPoint[j++]; } //讨论一点在左半边一点在右半边的情况 k = 0; for(i = 1; i<=right; i++){ if(fabs(p1.x-point[i-1].x)<d) point[k++] = point[i-1]; } for(i=0;i<k;i++){ for(j=i+1; point[j].y-point[i].y<d && j<k; j++){ d = min(d,dis(point[i],point[j])); } } return d; } int main() { cin >> M; for(int i = 0 ; i < M; i++){ //输入 input(); //排序 sort(p,p+N,cmp); //数组最小距离 double d = divide(0,N-1,p); printf("%.2lf\n",d); } //for_each(points.begin(),points.end(), showMinDistance);//first和last都是迭代器对象,至于第三个参数会自己取内容传入 /* for(vector<Point>::iterator i = points.begin();i != points.end();i++){//迭代器本质上是指向向量中对象的指针 cout << i->x << i->y << endl; } */ return 0; }
#include <iostream> using namespace std; int N; long long Count = 0; int a[50001],b[50001]; void input(){ scanf("%d", &N); for(int i=0;i<N;i++){ scanf("%d", &a[i]); } } //用归并排序(分治) void solve(int left, int right){ if(left >= right) return; int mid = (left + right)/2; solve(left,mid); solve(mid+1,right); int i=left, j=mid+1, k=0; while (i<=mid && j<=right){ if(a[i] > a[j]) { b[k++] = a[j++]; Count += mid-i+1; } else{ b[k++] = a[i++]; } } while (i <= mid){ b[k++] = a[i++]; } while (j<= right){ b[k++] = a[j++]; } for(int i=left,j=0; i<=right; i++,j++){ a[i] = b[j]; } } int main() { int M; cin >> M; for(int i=0; i<M; i++){ input(); solve(0,N-1); cout << Count << endl; Count = 0; } return 0; }
#include <iostream> using namespace std; int N; long long Count = 0; int a[50001],b[50001]; void input(){ scanf("%d", &N); for(int i=0;i<N;i++){ scanf("%d", &a[i]); } } //用归并排序(分治) void solve(int left, int right){ if(left >= right) return; int mid = (left + right)/2; solve(left,mid); solve(mid+1,right); int i=left, j=mid+1, k=0; while (i<=mid && j<=right){ if(a[i] > a[j]) { b[k++] = a[j++]; Count += mid-i+1; } else{ b[k++] = a[i++]; } } while (i <= mid){ b[k++] = a[i++]; } while (j<= right){ b[k++] = a[j++]; } for(int i=left,j=0; i<=right; i++,j++){ a[i] = b[j]; } } int main() { int M; cin >> M; for(int i=0; i<M; i++){ input(); solve(0,N-1); cout << Count << endl; Count = 0; } return 0; }
#include <iostream> #include <algorithm> using namespace std; int N,X; int a[50001]; void input(){ scanf("%d %d",&N,&X); for(int i=0; i<N; i++){ scanf("%d",&a[i]); } } bool binary_search(int x, int low, int high){ if(low > high){//出口设置要谨慎 return false; } int mid = (low + high)/2; if(a[mid] == x){ return true; } else if(a[mid] < x){ binary_search(x,mid+1,high); } else { binary_search(x,low,mid-1); } } void solve(){ int m,count = 0; for(int i=0; i<N; i++){ m = X - a[i]; if(binary_search(m,0,N-1)){ count++; } } if(count !=0){ cout << "yes" << endl; } else{ cout << "no" << endl; } } int main() { int M; cin >> M; for(int i=0; i<M; i++){ input(); sort(a,a+N); solve(); } return 0; }
#include <iostream> #include <string> #include <cstring> using namespace std; int main() { int n;//记录组数 cin >> n; int Input[3]; int Answer[n]; char str[41]; int dp[41][7];//用矩阵存放乘积中间结果 int num[41][41]; //格式输入 unsigned char c; c = getchar(); for (int t = 0; t < n; ++t) { int j = 0; //分割字符,控制输入 while ((c=getchar())!='\n'){ if(c != ' '){ ungetc(c,stdin); cin >> Input[j++]; } } //开始处理 //数字入num for(int i=0;i<Input[0];i++){ itoa(Input[2],str,10); int temp = 0; for(int j=i;j<Input[0];j++){ temp = temp*10 + str[j] - '0'; num[i][j] = temp; } } //用0初始化 memset(dp, 0, sizeof(dp)); memset(num, 0, sizeof(num)); //当不插入乘号后,最大乘积为本身 for (int i = 0; i < Input[0]; ++i) { dp[i][0] = num[0][i]; } //动态转移方程,更新解 for (int i = 0; i < Input[0]; ++i) { for (int k = 1; k <= Input[1]; ++k) { for (int l = 0; l < i; ++l) { dp[i][k] = max(dp[l][k-1]*num[l+1][i],dp[i][j]); } } } Answer[t] = dp[Input[0]-1][Input[1]]; } for (int i = 0; i < n; ++i) { cout << Answer[i] << endl; } return 0; }
#include <iostream> using namespace std; int N; int maxSum = 0; int a[50001]; void input(){ scanf("%d", &N); for(int i=0;i<N;i++){ scanf("%d", &a[i]); } } void solve(){ int dp[N]; //初始化 dp[0] = a[0]; maxSum = a[0]; for(int i=1; i<N; i++){ if(dp[i-1] < 0){ dp[i] = a[i];//如果之前的加和结果已然为-,评价为应该从头开始 } else{ dp[i] = dp[i-1] + a[i]; maxSum = max(dp[i],maxSum); } } } int main() { int M; cin >> M; for(int i=0; i<M; i++){ input(); solve(); cout << maxSum << endl; maxSum = 0; } return 0; }
#include <iostream> using namespace std; int INT_MIN = -100; int main(){ int m,n,C; cin>>m; while(m--){ cin>> n >> C;//n是宝石数目,c是背包容量 int w[n+1],v[n+1],dp[C+1];//w是重量,v是价值 dp[0]=0; for(int i=1;i<=C;i++) dp[i]=INT_MIN; for(int i=1;i<=n;i++){ cin>>w[i]>>v[i]; } //动态规划问题 for(int i=1; i<=n; i++) for(int j=C; j>=w[i]; j--) dp[j]=max(dp[j],dp[j-w[i]]+v[i]); if(dp[C]<0) dp[C]=0; cout << dp[C] << endl; } return 0; }
#include <iostream> #include <iomanip> using namespace std; #define INF 0X3f3f3f3f int key[500]; double p[501], q[501], c[501][501], w[501][501]; void BST(double p[], double q[], int n){ for(int i=0; i<=n; i++){ c[i][i] = 0;//c(i,j)表示第i+1到j个key构造的最优二叉树的代价(平均搜索长度asl,找到和没找到要加起来),则c(0,n)是最后结果 w[i][i] = q[i];//w(i,j)表示第i+1到j个key权值及第i到j个空隙权值(空隙权值就是关键字外的搜索概率)和 } for(int x=1; x<=n; x++){ for(int i=0; i<=n-x; i++){ int j = i + x;//不断以i到j为内容建树(迭代) c[i][j] = INF; w[i][j] = w[i][j-1] + p[j] + q[j]; for(int k=i+1; k<=j; k++){//以k为根的最优二叉树代价 c[i][j] = min(c[i][j],w[i][j]+c[k][j]+c[i][k-1]); } } } } int main() { int M, N; cin >> M; for(int i=0; i<M; i++){ cin >> N; for(int j = 0; j<N; j++) cin >> key[j];//N个从小到大排好的数 for(int j = 1; j<=N; j++) cin >> p[j];//N个关键字搜索概率 for(int j = 0; j<=N; j++) cin >> q[j];//搜索关键字外的概率 BST(p,q,N); //最终结果是从c[0][N],前面c[i][j]是不断建树记录的过程 cout << fixed<<setprecision(6)<< c[0][N] << endl; } return 0; }
#include <cstdio> #include <algorithm> #include <iostream> using namespace std; int A[10001], dp[10001], N; // 序列和, dp数组, 数字总数 void input(){ scanf("%d", &N); for(int i=0; i<N; i++){ scanf("%d", &A[i]); } } void solve(){ int ans = -1; // 记录最大的 dp[i] for(int i = 0; i < N; i++) { dp[i] = 1; // 至少能够自身成为一条 LIS for(int j = 0; j < i; j++){ // 只需要递归到小于 i // 如果不比之前的小,而且新形成的子序列更大,则接到这个人后面来 if(A[i] >= A[j] && (dp[j] + 1 > dp[i])) { dp[i] = dp[j] + 1; } } ans = max(ans, dp[i]); // 确定当前结束的最长子序列的长度之后,比较 } printf("%d", ans); } int main() { int M; cin >> M; for(int i=0; i<M; i++){ input(); solve(); } return 0; }
#include <iostream> #include <stack> #include <algorithm> using namespace std; int N; int a[10001], ct[10001]; stack<int> a_stack; void input(){ scanf("%d", &N); for(int i=0; i<N; i++){ scanf("%d", &a[i]); } } int clear_stack(){ int c = 0; while (!a_stack.empty()){ a_stack.pop(); c++; } return c; } void solve(){ for(int i=0; i<N; i++){ a_stack.push(a[i]); int s_stack_t = a[i]; for(int j=i+1; j<N; j++){ if(a[j] >= a_stack.top()){ s_stack_t = a_stack.top(); a_stack.push(a[j]); } if(a[j] < a_stack.top() && a[j] >= s_stack_t){//为求最长子序列,入栈的元素曲线要尽可能平滑 a_stack.pop(); s_stack_t = a_stack.top(); a_stack.push(a[j]); } } ct[i] = clear_stack(); } } void output(){ sort(ct,ct+N); cout << ct[N-1] << endl; } int main() { int M; cin >> M; for(int i=0; i<M; i++){ input(); solve(); output(); } return 0; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。