360机试
一、
1、
#include<iostream> #include<algorithm> using namespace std; struct node{ //结构体定义点 int x; int y; }d[1000]; int main() { int n; while(cin>>n) { int xmin,xmax,ymin,ymax; //四个最大最小坐标点 for(int i=0;i<n;i++) { cin>>d[i].x>>d[i].y; } xmin=d[0].x; //赋初始值 xmax=d[0].x; ymin=d[0].y; ymax=d[0].y; for(int i=1;i<n;i++) { if(xmin>d[i].x){ xmin=d[i].x; } if(xmax<d[i].x){ xmax=d[i].x; } if(ymin>d[i].y){ ymin=d[i].y; } if(ymax<d[i].y){ ymax=d[i].y; } } int l; l=max(xmax-xmin,ymax-ymin); //求出面积 cout<<l*l; } return 0; }
通过率36% ,由于忽略了int 的范围。
int 范围 [-2^31 , 2^31 -1] 即 [-2147483648,2147483647]
所以很容易溢出。
出错
2、
#include<iostream> #include<algorithm> using namespace std; struct node{ //结构体定义点 long long x,y; }d[1000]; int main() { int n; while(cin>>n) { long long xmin,xmax,ymin,ymax; //四个最大最小坐标点 for(int i=0;i<n;i++) { cin>>d[i].x>>d[i].y; } xmin=d[0].x; //赋初始值 xmax=d[0].x; ymin=d[0].y; ymax=d[0].y; for(int i=1;i<n;i++) { if(xmin>d[i].x){ xmin=d[i].x; } if(xmax<d[i].x){ xmax=d[i].x; } if(ymin>d[i].y){ ymin=d[i].y; } if(ymax<d[i].y){ ymax=d[i].y; } } long long l; l=max(xmax-xmin,ymax-ymin); //求出面积 cout<<(l*l); } return 0; } // 2 800000000 900000000 -800000000 -900000000
用 long long 数据格式才可以。
各种数据类型范围
二、
#include<iostream> #include<algorithm> #include<vector> #include<set> using namespace std; struct Que{ int s; int e; }; int N[2001]={0}; int ans[1000000]={0}; int Inqury(int a,int b,int *q) { set<int> s; for(int i=a;i<=b;i++) { s.insert(q[i]); } return s.size(); } int main() { int n,m,q; while(cin>>n>>m) { for(int i=1;i<=n;i++) { cin>>N[i]; } cin>>q; for(int i=0;i<q;i++) { int s,e,Num; cin>>s>>e; Num=Inqury(s,e,N); ans[i]=Num; } for(int i=0;i<q;i++) { cout<<ans[i]<<endl; } } }
测试用例:
8 6 1 3 2 2 4 2 5 6 3 1 3 2 5 1 6
三、
四、
1、
1.1
public static int win1(int[] arr) { if (arr == || arr.length == 0) { return 0; } return Math.max(f(arr, 0, arr.length - 1), s(arr, 0, arr.length - 1)); } public static int f(int[] arr, int i, int j) { if (i == j) { return arr[i]; } return Math.max(arr[i] + s(arr, i + 1, j), arr[j] + s(arr, i, j - 1)); /*当i!=j时,说明至少还有两张纸牌,那么先手的人就有选择,是先拿第一张,还是拿最后一张。 如果拿了第一张,那么剩下i+1到j的牌里他就是后手, 同理先拿了最后一张,那么他在i到j-1里后手。 都是绝对理性的个体,所以两者选大的拿走即为他的分数。*/ } public static int s(int[] arr, int i, int j) { if (i == j) { return 0; } return Math.min(f(arr, i + 1, j), f(arr, i, j - 1)); /*当i!=j时,说明至少还有两张纸牌,那么先手的人就有选择,是先拿第一张,还是拿最后一张。 如果拿了第一张,那么后手的人在剩下i+1到j的牌里他就是先手, 同理如果先手拿了最后一张,那么后手的人在i到j-1里先手。 都是绝对理性的个体,所以先手一定会把更小的留给他。*/ }
1.2 动态规划 解法
#include <iostream> #include <vector> #include<string.h> using namespace std; int cardGame(vector<int> A, int n) { //纸牌博弈 int dp[n][n]={0}; int dp1[n][n]={0}; //置0; //memset(dp,0,sizeof(dp)); //memset(dp1,0,sizeof(dp1)); //置0 的另一种方法,库为 string.h for(int j = 0 ;j < n ; j++) { dp[j][j] = A[j]; for(int i = j - 1;i >= 0; i--) { dp[i][j] = max((A[i] + dp1[i + 1][j]) , (A[j] + dp1[i][j - 1])); dp1[i][j] = min(dp[i + 1][j] , dp[i][j - 1]); } } cout<<endl; for(int i=0;i<n;i++) { for(int j=0;j<n;j++) cout<<dp[i][j]<<" "; cout<<endl; } cout<<endl; for(int i=0;i<n;i++) { for(int j=0;j<n;j++) cout<<dp1[i][j]<<" "; cout<<endl; } cout<<endl; return max(dp[0][n - 1],dp1[0][n - 1]); } int main() { int T = 0; cin >> T; //测试用例数 vector<int> vec; for(int i=0;i<T;i++) { int tem; cin>>tem; vec.push_back(tem); } cout<<cardGame(vec,T); return 0; } //4 1 2 100 4 //6 4 7 2 9 5 2 // 4 4 7 2 2
3、来回挑最大的
#include <iostream> #include <vector> #include<string.h> using namespace std; int main() { int T = 0; cin >> T; //测试用例数 vector<int> vec; for(int i=0;i<T;i++) { int tem; cin>>tem; vec.push_back(tem); } int a=0,b=0; int flag=0; while(vec.size()>0) { if(flag==0) { a+=max(vec[0],vec[vec.size()-1]); if(vec[0]>=vec[vec.size()-1]) vec.erase(vec.begin()); else vec.pop_back(); flag=1; } else { b+=max(vec[0],vec[vec.size()-1]); if(vec[0]>=vec[vec.size()-1]) vec.erase(vec.begin()); else vec.pop_back(); flag=0; } } cout<<a<<" "<<b; return 0; } //4 1 2 100 4 //6 4 7 2 9 5 2 // 4 4 7 2 2
该题是上题的变形。
五、内存管理
#include <iostream> #include <vector> #include <string> using namespace std; struct mem //定义结构体 { int no; //编号,内存,开始,结束 int size; int start; int end; }; vector<mem> vec; int cnt = 0; int tail; int del(int no) { for (vector<mem>::iterator it = vec.begin(); it != vec.end(); it++) { if ((*it).no == no) { vec.erase(it); return no; } } return -1; } int def() { for (vector<mem>::iterator it = vec.begin() + 1; it != vec.end() - 1; it++) { if ((*it).no == 0) { continue; } (*it).start = (*(it - 1)).end + 1; (*it).end = (*it).start + (*it).size - 1; } if (vec.size() == 2) { tail = (*(vec.end() - 1)).start; } else { tail = (*(vec.end() - 1)).start - (*(vec.end() - 2)).end - 1; } return -1; } int newMem(int sz) { for (vector<mem>::iterator it = vec.begin() + 1; it != vec.end(); it++) { if ((*it).start - (*(it - 1)).end - 1 >= sz) { cnt++; mem tmp = { cnt, sz, (*(it - 1)).end + 1, (*(it - 1)).end + sz }; vec.insert(it, 1, tmp); tail -= sz; return cnt; } } vector<mem>::reverse_iterator it = vec.rbegin(); if (tail >= sz) { cnt++; vec.push_back({ cnt, sz, (*it).end + 1, (*it).end + sz }); tail -= sz; return cnt; } return -1; } int main() { int n = 0; while (cin >> n >> tail) //n,输入任务 ;tail内存 { vec.clear(); cnt = 0; vec.push_back({ 0, 0, -1, -1 }); vec.push_back({ 0, 0, tail, -1 }); string str; while (n--) { cin >> str; if (str.compare("new") == 0) { int sz; cin >> sz; int res = newMem(sz); if (res == -1) { //printf("NULL\n"); cout<<"NULL"<<endl; } else { cout << res << endl; } } else if (str.compare("del") == 0) //删除 { int tmp; cin >> tmp; if (tmp <= 0) { //printf("ILLEGAL_OPERATION\n"); cout<<"ILLEGAL_OPERATION"<<endl; } else { int res = del(tmp); if (res == -1) { //printf("ILLEGAL_OPERATION\n"); cout<<"ILLEGAL_OPERATION"<<endl; } } } else //def { def(); } for(int i=0;i<vec.size();i++) { cout<<vec[i].no<<" "<<vec[i].size<<" "<<vec[i].start<<" "<<vec[i].end<<endl; } } } return 0; }
样例
6 10 new 5 new 3 del 1 new 6 def new 6
2、
#include <iostream> #include <vector> #include <string> using namespace std; struct mem //定义结构体 { int no; //编号,内存,开始,结束 int size; int start; int end; }; vector<mem> vec; int cnt = 0; int tail; int del(int no) { for (int i=0; i<vec.size(); i++) { if (vec[i].no == no) { vec.erase(vec.begin()+i); return no; } } return -1; } int def() { for (int i =1; i<vec.size() - 1; i++) { if (vec[i].no == 0) { continue; } vec[i].start = vec[i-1].end + 1; vec[i].end = vec[i].start + vec[i].size - 1; } return -1; } int newMem(int sz) { for (int i= 1; i< vec.size(); i++) { if (vec[i].start - vec[i-1].end - 1 >= sz) { cnt++; mem tmp = { cnt, sz, vec[i-1].end + 1, vec[i-1].end + sz }; vec.insert(vec.begin()+i, 1, tmp); return cnt; } } return -1; } int main() { int n = 0; while (cin >> n >> tail) //n,输入任务 ;tail内存 { vec.clear(); cnt = 0; vec.push_back({ 0, 0, -1, -1 }); vec.push_back({ 0, 0, tail, -1 }); string str; while (n--) { cin >> str; if (str.compare("new") == 0) { int sz; cin >> sz; int res = newMem(sz); if (res == -1) { cout<<"NULL"<<endl; } else { cout << res << endl; } } else if (str.compare("del") == 0) //删除 { int tmp; cin >> tmp; if (tmp <= 0) { cout<<"ILLEGAL_OPERATION"<<endl; } else { int res = del(tmp); if (res == -1) { cout<<"ILLEGAL_OPERATION"<<endl; } } } else //def { def(); } for(int i=0;i<vec.size();i++) { cout<<vec[i].no<<" "<<vec[i].size<<" "<<vec[i].start<<" "<<vec[i].end<<endl; } } } return 0; }
将迭代器换成了下标表示。
1 5 0 4 分别表示第1个任务,占据5个内存,内存地址开始为0,结束为4
2 3 5 7 表示第2个任务,占据3个内存,内存地址开始为5,结束为7
0 0 10 -1 默认存储最大值为10
del 就是查询下标,vector 删除
new 依次查询,相邻任务间的内存差值,大于要存的内容,就保存。例如,上面任务2存在位置5到7,占了3个内存。所以用2号任务开始的地址减去上一个任务结束的地址,可以知道他们之间有了5-(-1)-1=5的内存空间,如果该内存空间大于目标内存,就可以将目标内存存在该处;
def 首先找到任务编号为1的任务,然后将其开始内存地址置为0( vec[i-1].end + 1;),然后结束坐标地址为开始地址加上内存空间;下一个任务,开始地址为上一个任务结束地址+1;
这样就实现了内存管理。