赞
踩
1001:A+B Format (20 分)(AC:stack)
注意要点:
1.注意0的时候的问题。
- #include<iostream>
- #include<stack>
- using namespace std;
-
- stack<char> s;
-
- int main(){
- int a , b , count = 0 , n = 0;
- scanf("%d %d" , &a , &b);
- int t = a + b;
- //全是对于t的正数操作//
- if(t < 0){
- t = -t;
- }
- //对于 t 的处理//
- while(t != 0){
- char c = t % 10 + '0';
- s.push(c);
- count ++;
- if(count == 3){
- s.push(',');
- count =0;
- }
- t /= 10;
- }
- //判断正负//
- if(a + b < 0){
- printf("-");
- }
- if(a + b == 0){
- printf("0");
- return 0;
- }
- //输出//
- while(!s.empty()){
- if(n == 0 && s.top() == ','){
- s.pop();
- n ++;
- continue;
- }
- printf("%c" , s.top());
- s.pop();
- n ++;
- }
- return 0;
- }
1002:A+B for Polynomials (25)(AC)
注意要点:
1.float数组类型初始化的时候切记内部数字也得是0.0,要不然真的死都不知道怎么死的。
2.多组数据只要是后面不用的,都可以共用一个。
- #include<iostream>
- using namespace std;
- int main() {
- int M;
- int a;
- float b;
- int num = 0;
- float p[1005] = {0.0} ; //注意这个地方//
- scanf("%d" , &M);
- //第一行//
- for(int i = 0 ; i < M ; i ++) {
- scanf("%d %f" , &a , &b);
- p[a] += b ;
- }
- //第二行//
- getchar();
- scanf("%d" , &M);//可以直接覆盖//
- for(int i = 0 ; i < M ; i ++) {
- scanf("%d %f" , &a , &b);
- p[a] += b; //在第一行基础之上往上加//
- }
- //统计个数//
- for(int i = 0 ; i < 1005 ; i ++){
- if(p[i] != 0) num ++;
- }
- printf("%d" , num);
- for(int i = 10 ; i >= 0 ; i --){
- if(p[i] != 0)
- printf(" %d %.1f" , i , p[i]);
-
- }
- return 0;
- }
1003:Emergency (25 分)(AC)
注意要点:
1.Dijkstra + BFS
- #include<iostream>
- #include<algorithm>
- #include<cstring>
- using namespace std;
- const int MAXV = 505;
- const int INF = 1000000;
-
- int G[MAXV][MAXV] , num[MAXV] , w[MAXV] , d[MAXV] , weight[MAXV];
- int N , M , S , D;
- bool vis[MAXV] = { 0 };
-
- void Dijkstra(int S){
- //初始化//
- fill(d , d + MAXV , INF);
- memset(w , 0 , sizeof(w));
- memset(num , 0 , sizeof(num));
- //开始各种标记//
- d[S] = 0;
- w[S] = weight[S];
- num[S] = 1;
- //遍历每个点//
- for(int i = 0 ; i < N ; i ++) {
- //找到d之中最小的//
- int u = -1 , MIN = INF;
- for(int j = 0 ; j < N ; j ++){
- if(vis[j] == false && d[j] < MIN){
- u = j;
- MIN = d[j];
- }
- }
- //特殊情况找不到,退出//
- if(u == -1) return ;
- vis[u] = true;
- //修改值//
- for(int v = 0 ; v < N ; v ++) {
- if(vis[v] == false && G[u][v] != INF){
- if(d[u] + G[u][v] < d[v]){
- d[v] = d[u] + G[u][v];
- w[v] = w[u] + weight[v];
- num[v] = num[u];
- }
- else if(d[u] + G[u][v] == d[v]){
- if(w[u] + weight[v] > w[v])
- w[v] = w[u] + weight[v];
- num[v] += num[u];
- }
- }
- }
- }
- }
-
- int main() {
- int a , b , c;
- scanf("%d %d %d %d" , &N , &M , &S , &D);
- for(int i = 0 ; i < N ; i ++) {
- scanf("%d" , &weight[i]);//救援队既是权值//
- }
-
- fill(G[0] , G[0] + MAXV * MAXV , INF);
-
- for(int i = 0 ; i < M ; i ++) {
- scanf("%d %d %d" , &a , &b , &c);
- G[a][b] = c;
- G[b][a] = c;
- }
- Dijkstra(S);
- printf("%d %d\n" , num[D] , w[D]);
- return 0;
- }
1004:Counting Leaves (30 分)(AC:DFS)
注意要点:
1.一开始的思路是去建立一棵树,想了想发现DFS也可以做出来。
2.强化DFS问题解决方式:递归 + 边界判断。
- #include<iostream>
- #include<vector>
- using namespace std;
- const int MAXN = 105;
-
- vector<int> v[MAXN];
- int J[MAXN];
- int D = -1;
-
- void DFS(int x , int depth){
- //边界//
- if(v[x].size() == 0){
- J[depth] ++;
- D = max(depth , D);
- return ;
- }
- //递归//
- for(int i = 0 ; i < v[x].size() ; i ++){
- DFS(v[x][i] , depth + 1);
- }
- }
-
- int main(){
- int N , M , ID , K , a;
- //输入//
- scanf("%d %d" , &N , &M);
- for(int i = 0 ; i < M ; i ++){
- scanf("%d %d" , &ID , &K);
- for(int j = 0 ; j < K ; j ++){
- scanf("%d" , &a);
- v[ID].push_back(a);
- }
- }
- //DFS//
- DFS(1 , 0);
- //输出//
- for(int i = 0 ; i <= D ; i ++){
- if(i == 0){
- printf("%d" , J[i]);
- }
- else{
- printf(" %d" , J[i]);
- }
- }
- return 0;
- }
1005:Spell It Right (20 分)(AC:Vector)
注意要点:
1.0的情况考虑一下。
- #include<iostream>
- #include<vector>
- using namespace std;
-
- vector<int> v;
-
- int main(){
- int sum = 0 ;
- char a;
- char b[10][10] = {"zero" , "one" , "two" , "three" , "four" , "five" , "six" , "seven" , "eight" , "nine"};
- //输入//
- while(scanf("%c" , &a) == 1){
- if(a != '\n')
- sum =sum + (a - '0');
- }
- //倒着插入//
- if(sum == 0){
- printf("zero");
- }
- else{
- while(sum != 0){
- int c = sum % 10;
- v.push_back(c);
- sum /= 10;
- }
- //输出//
- for(int i = v.size() - 1 ; i >= 0 ; i --){
- if(i == v.size() - 1){
- printf("%s" , b[v[i]]);
- }
- else{
- printf(" %s" , b[v[i]]);
- }
- }
- }
- return 0;
- }
1007:Maximum Subsequence Sum (DP)
掌握了一个基本的dp问题的思路。
先写边界,随后确定递推公式。基本的模型一定要先理解清楚,随后做题才能在此基础之上进一步求解。
- #include<iostream>
- using namespace std;
- const int MAXN = 10005;
-
- int main(){
- int K;
- int a[MAXN] , dp[MAXN];//dp的含义是指,在这个数值状态下的最大的数值是多少//
- int s[MAXN] = { 0 };
- bool flag = true;
-
- scanf("%d" , &K);
- for(int i = 0 ; i < K ; i ++){
- scanf("%d" , &a[i]);
- if(a[i] >= 0){
- flag = false;
- }
- }
- if(flag == true){//如果有一个数字是负数的话,则直接输出//
- printf("%d %d %d" , 0 , a[0] , a[K - 1]);
- return 0;
- }
- dp[0] = a[0];//第一个数值就是其本身//
- for(int i = 1 ; i < K ; i ++){
- if(dp[i - 1] + a[i] > a[i]){ //
- dp[i] = dp[i - 1] + a[i];
- s[i] = s[i - 1];
- }
- else{
- dp[i] = a[i];
- s[i] = i;
- }
- }
- int n = 0;
- for(int i = 1 ; i < K ; i ++){
- if(dp[i] > dp[n]){
- n = i;
- }
- }
- printf("%d %d %d\n" , dp[n] , a[s[n]] , a[n]);
- return 0;
- }
1008:Elevator (20 分)(AC:vector数学问题)
注意要点:
无。
- #include<iostream>
- #include<vector>
- using namespace std;
-
- vector<int> v;
-
- int main(){
- int N , a , d = 0;
- //输入//
- scanf("%d" , &N);
- for(int i = 0 ; i < N ; i ++){
- scanf("%d" , &a);
- v.push_back(a);
- }
- //层数操作//
- for(int i = 0 ; i < v.size() ; i ++){
- //一层//
- if(i == 0){
- d = d + (v[i] - 0) * 6 + 5;
- }
- //二层以上 , 比你高//
- else if( i != 0 && (v[i] > v[i - 1])){
- d = d + ((v[i] - v[i - 1]) * 6 + 5);
- }
- // 二层以上,比你低//
- else{
- d = d + ((v[i - 1] - v[i]) * 4 + 5);
- }
- }
- printf("%d" , d);
- return 0;
- }
1009:Product of Polynomials (25 分)(AC:数学模拟)
注意要点:
1.审题,注意这个题目是要求乘法,我一开始做成加法了, 浪费了很多时间。
2.double类型只能由lf来接,否则都是根本接不到。
3.这个题思路也是很清晰,几乎不用拐弯,我开了两个数组的原因是不想交叉起来不好修改。
- #include<iostream>
- using namespace std;
- int main(){
- int N , M , a , c , maxn = -1 , count = 0;
- double b , d;
- double A[10000] = { 0 } , B[10000] = { 0 };
- //输入//
- scanf("%d" , &N);
- for(int i = 0 ; i < N ; i ++){
- scanf("%d %lf" , &a , &b);
- A[a] = A[a] + b;
- //边界//
- if(a > maxn){
- maxn = a;
- }
- }
- scanf("%d" , &M);
- for(int j = 0 ; j < M ; j ++){
- scanf("%d %lf" , &c , &d);
- //换到B数组里面//
- for(int i = maxn ; i >= 0 ; i --){
- if(A[i] != 0){
- B[i + c] = B[i + c] + d * A[i];
- if(i + c > maxn){
- maxn = i + c;
- }
- }
- }
- }
- for(int i = 0 ; i <= maxn ; i ++){
- if(B[i] != 0){
- count ++;
- }
- }
- //输出//
- printf("%d " , count);
- for(int i = maxn ; i >= 0 ; i --){
- if(B[i] != 0.0){
- printf("%d %.1lf" , i , B[i]);
- count --;
- if(count > 0)
- printf(" ");
- }
- }
- return 0;
- }
1011:World Cup Betting (20 分)(AC:数学模拟)
注意要点:
1.这个输出着实牛啤,还能这么输出。
- #include<iostream>
- using namespace std;
-
- int main(){
- float a, sum = 1 ;
- int k;
- char S[3] = {'W' , 'T' , 'L'};//对应字符表//
- //输入//
- for(int i = 0 ; i < 3 ; i ++){
- float max = -1.0 ;
- for(int j = 0 ; j < 3 ; j ++){
- scanf("%f" , &a);
- if(a > max){
- max = a;
- k = j;
- }
- }
- printf("%c " , S[k]);
- sum *= max;
- }
- //输出2//
- printf("%.2f" , (sum * 0.65 - 1) * 2);
- return 0;
- }
1013:Battle Over Cities (25 分)(AC :DFS , 并查集)
注意要点:
1.dfs之后改用连接表,不要使用图了。
- #include<iostream>
- #include<algorithm>
- #include<cstring>
- #include<vector>
- using namespace std;
- const int INF = 10000000;
-
- vector<int> v[1005];
- int c;
- bool vis[1005];
- void dfs(int e){
- if(e == c) return ;
- vis[e] = true;
- for(int i = 0 ; i < v[e].size() ; i ++){
- if(vis[v[e][i]]== false){
- dfs(v[e][i]);
- }
- }
- }
-
- int main(){
- int N , M , K ,a , b;
- //输入//
- scanf("%d %d %d" , &N , &M , &K);
- for(int i = 0 ; i < M ; i ++){
- scanf("%d %d" , &a , &b);
- v[a].push_back(b);
- v[b].push_back(a);
- }
- //输出//
- for(int i = 0 ; i < K ; i ++){
- scanf("%d" , &c);
- memset(vis , false , sizeof(vis));
- int block = 0;
- for(int i = 1 ; i <= N ; i ++){
- if(i != c && vis[i] == false){
- dfs(i);
- block ++;
- }
- }
- printf("%d\n" , block - 1);
- }
- return 0;
- }
1020:Tree Traversals (25 分)(AC)
注意要点:
2.这个层序遍历的这个地方非常容易错,修改了两三次才AC了。
- #include<iostream>
- #include<queue>
- using namespace std;
- struct node{
- int data;
- node* lchild;
- node* rchild;
- };
-
- int pos[55] , in[55];
- int N;
- //利用后根数列和中根数列求原来的数列//
- node* creat(int posL , int posR , int inL , int inR) {
- //边界//
- if(posL > posR){
- return NULL;
- }
- //求根节点//
- node* root = new node;
- root->data = pos[posR];
- int k;
- for(k = inL ; k <= inR ; k ++) {
- if(in[k] == pos[posR])
- break;
- }
- //左右分支//
- int numleft = k - inL;
- root->lchild = creat(posL , posL + numleft - 1 , inL , k - 1);//易错//
- root->rchild = creat(posL + numleft , posR - 1, k + 1 , inR);
- return root;
- }
-
- //利用BFS来输出这个层序遍历。//
- int num = 0 ;
- void BFS(node* root) {
- queue<node*> q;
- q.push(root);
- while(!q.empty()){
- node* t = q.front();
- q.pop();
- printf("%d" , t->data);
- num ++;
- if(num < N) printf(" ");
- if(t->lchild != NULL) q.push(t->lchild);
- if(t->rchild != NULL) q.push(t->rchild);
- }
- }
-
- int main() {
- scanf("%d" , &N);
- for(int i = 0 ; i < N ; i ++) {
- scanf("%d" , &pos[i]);
- }
- for(int i = 0 ; i < N ; i ++) {
- scanf("%d" , &in[i]);
- }
- node* root = creat(0 , N - 1 , 0 , N - 1);
- BFS(root);
- return 0;
- }
1030:Travel Plan (30 分)(AC:Dijkstra第二形态 + 记忆化DFS)
注意要点:
1.这个地方注意这是个无向图。需要注意来回的数值都可以。
2.巧了,不知道为什么PTA的数值题目都可以用 Matrix 来做。看来数据还是小。
- #include<iostream>
- #include<algorithm>
- #include<vector>
- using namespace std;
- const int MAXN = 505;
- const int INF = 100005;
-
- //初始化定义//
- int G[MAXN][MAXN];
- int cost[MAXN][MAXN];
- int d[MAXN] , x[MAXN];
- int pre[MAXN];
- bool vis[MAXN];
- int N , M , S , D;
- int a , b , c , de;
-
- void Dijkstra(int s){
- fill(d , d + MAXN , INF);
- fill(x , x + MAXN , INF);
- //Ñ°ÕÒÇ°Çý½áµã//
- for(int i = 0 ; i < N ; i ++){
- pre[i] = i;
- }
- d[s] = 0;
- x[s] = 0;
- for(int i = 0 ; i < N ; i ++){
- int u = -1 , MIN = INF;
- //第一步:找最小值//
- for(int j = 0 ; j < N ; j ++){
- if(vis[j] == false && d[j] < MIN){
- MIN = d[j];
- u = j;
- }
- }
- //第二步:确定范围//
- if(u == -1) return ;
- //第三步:更新数值//
- vis[u] = true;
- for(int v = 0 ; v < N ; v ++){
- if(vis[v] == false && G[u][v] != INF){
- if(d[u] + G[u][v] < d[v]){
- d[v] = d[u] + G[u][v];
- x[v] = x[u] + cost[u][v];
- pre[v] = u;
- }
- else if(d[u] + G[u][v] == d[v]){
- if(x[u] + cost[u][v] < x[v]){
- x[v] = x[u] + cost[u][v];
- pre[v] = u;
- }
- }
- }
- }
- }
- }
-
- //记忆化搜索//
- void DFS(int v){
- if(v == S){
- printf("%d " , S);
- return ;
- }
- DFS(pre[v]);
- printf("%d " , v);
- }
-
- int main(){
- //初始化数据//
- fill(d , d + MAXN , false);
- fill(G[0] , G[0] + MAXN * MAXN , INF);
- //ÊäÈë//
- scanf("%d %d %d %d" , &N , &M , &S , &D);
- for(int i = 0 ; i < M ; i ++){
- scanf("%d %d %d %d" , &a , &b , &c , &de);
- G[a][b] = c;
- G[b][a] = c;
- cost[a][b] = de;
- cost[b][a] = de;
- }
- //最短路径//
- Dijkstra(S);
- //输出//
- DFS(D);
- printf("%d %d\n" , d[D] , x[D]);
- }
1031:Hello World for U (20 分)(AC:打印图案)
思路提示:
1.首先需要确定n1 , n2 , n3的数值,其次按照边框再每一个打印出来,最后二维数组写出。
注意要点:
1.最后强调一次这个memset这个功能。在cstring头文件下。
- #include<iostream>
- #include<cstring>
- using namespace std;
- int main(){
- char s[100];
- char m[100][100];
- memset(m , ' ' , sizeof(m));
- scanf("%s" , s);
- //确定n1 , n2 , n3 //
- int len = strlen(s) + 2;
- int n1 = len / 3;
- int n3 = n1;
- int n2 = len / 3 + len % 3;
- //填入数组中//
- int k = 0 ;
- for(int i = 0; i < n1 ; i ++){//n1//
- m[i][0] = s[k ++];
- }
- for(int i = 1 ; i <= n2 - 2 ; i ++){//n2//
- m[n1 - 1][i] = s[k ++];
- }
- for(int i = n3 - 1 ; i >= 0 ; i --){//n3//
- m[i][n2 - 1] = s[k ++];
- }
- //输出//
- for(int i = 0 ; i < n1 ; i ++){
- for(int j = 0 ; j < n2 ; j ++){
- printf("%c" , m[i][j]);
- }
- printf("\n");
- }
- return 0;
- }
1033:Sharing (25 分)(AC:模拟链表)
思路提示:
1.模拟链表的技巧。
注意要点:
%05d,超容易犯错。
- #include<iostream>
- const int MAXN = 100005;
- using namespace std;
- struct node{
- char data;
- int next;
- }Node[MAXN];
- int main(){
- int s1 , s2 , n , a , c , k = 0;
- char b;
- bool L[MAXN] = { false };
- //输入//
- scanf("%d %d %d" , &s1 , &s2 , &n);
- for(int i = 0 ; i < n ; i ++){
- scanf("%d %c %d" , &a , &b , &c);
- Node[a].data = b;
- Node[a].next = c;
- }
- //第一轮//
- int root = s1;
- while(root != -1){
- L[root] = true;
- root = Node[root].next;
- }
- L[root] = true;
-
- //第二轮:找交点//
- int root2 = s2;
- while(root2 != -1){
- if(L[root2] == true){
- printf("%05d" , root2);
- L[root2] = false;//防止下次判断//
- break;
- }
- root2 = Node[root2].next;
- }
- if(L[root2] == true)
- printf("-1");
- return 0;
- }
1035:Password (20 分)(AC::水题)
思路提示:请认真读题。
注意要点:
1.这个地方注意这个多数和单一的情况。
- #include<iostream>
- #include<cstring>
- using namespace std;
- struct A{
- string b;//第一个字符串//
- string c;//第二个字符串//
- bool flag;//判断这个是否修改过//
- }a[1005];
-
- int main(){
- int n , count = 0;
- scanf("%d" , &n);
- for(int i = 0 ; i < n ; i ++){
- cin >> a[i].b >> a[i].c;
- for(int j = 0 ; j < a[i].c.size() ; j ++){//不停的进行修改保存//
- if(a[i].c[j] == '1'){
- a[i].c[j] = '@';
- a[i].flag = 1;
- continue;
- }
- if(a[i].c[j] == '0'){
- a[i].c[j] = '%';
- a[i].flag = 1;
- continue;
- }
- if(a[i].c[j] == 'l'){
- a[i].c[j] = 'L';
- a[i].flag = 1;
- continue;
- }
- if(a[i].c[j] == 'O'){
- a[i].c[j] = 'o';
- a[i].flag = 1;
- continue;
- }
- }
- if(a[i].flag == 1){
- count ++;//有问题个数的统计//
- }
- }
- //输出//
- if(n == 1 && count == 0){//1的情况//
- printf("There is 1 account and no account is modified");
- }
- else if(count == 0){//多数的情况//
- printf("There are %d accounts and no account is modified" , n);
- }
- else{//输出错误的情况//
- printf("%d\n" , count);
- for(int i = 0 ; i < n ; i ++){
- if(a[i].flag == 1){
- cout << a[i].b << " " << a[i].c;
- count --;
- if(count != 0){
- printf("\n");
- }
- }
- }
- }
- return 0;
- }
1036:Boys vs Girls (25 分)(AC :水题)
注意要点:注意读题,缺的地方写Absent。
- #include<iostream>
- #include<cstring>
- #include<math.h>
- using namespace std;
-
- int main(){
- int n , maxm = 10000 , maxn = -1 ;
- string maxmID , maxmname , maxnID , maxnname;
- scanf("%d" , &n);
- for(int i = 0 ; i < n ; i ++){
- int number;
- char sex ;
- string ID , name;
- cin >> name >> sex >> ID >> number;
- if(sex == 'M' && maxm > number){//成绩为男性//
- maxmname = name;
- maxmID = ID;
- maxm = number;
- }
- if(sex == 'F' && maxn < number){//成绩为女性//
- maxnname = name;
- maxnID = ID;
- maxn = number;
- }
- }
- //输出//
- if(maxm == 10000 || maxn == -1){//缺一个//
- if(maxm == 10000)
- cout << maxnname << " " << maxnID << endl << "Absent" << endl << "NA";
- if(maxn == -1)
- cout << "Absent" << endl << maxmname << " " << maxmID << endl << "NA";
-
- }
- else{//全有//
- cout << maxnname << " " << maxnID << endl;
- cout << maxmname << " " << maxmID << endl;
- printf("%d" , abs(maxn - maxm));
- }
- return 0;
- }
1040:Longest Symmetric String (25 分)(AC:DP)
注意要点:控制每次移动的长度,从1-3。
- #include<iostream>
- #include<cstring>
- using namespace std;
-
- int dp[1005][1005];
-
- int main(){
- string s;//注意小写string//
- int ans = 1;
- getline(cin , s);//专用空格//
- int len = s.size();
- memset(dp , 0 , sizeof(dp));//长度为 1和 2 的情况//
- for(int i = 0 ; i < len ; i ++){
- dp[i][i] = 1;
- if(i < len - 1){
- if(s[i] == s[i + 1]){
- dp[i][i + 1] = 1;
- ans = 2;
- }
- }
- }
- //处理数据长度为3//
- for(int L = 3 ; L <= len ; L ++){
- for(int i = 0 ; i + L - 1 < len ; i ++){
- int j = i + L - 1;//记录末尾值//
- if(s[i] == s[j] && dp[i + 1][j - 1] == 1){
- dp[i][j] = 1;
- ans = L;
- }
- }
- }
- printf("%d" , ans);
- return 0;
- }
1043:Is It a Binary Search Tree (25 分)(AC)
注意要点:
这个题目非常好,典型的二叉搜索树的体现。操作类似于树的操作。
- #include<iostream>
- #include<vector>
- using namespace std;
-
- struct node{
- int data;
- node *left;
- node *right;
- };
-
- void insert(node* &root , int a) {
- if(root == NULL){
- root = new node;
- root->data = a;
- root->left = NULL;
- root->right = NULL;
- return ;
- }
- if(a < root->data) insert(root->left , a);
- else insert(root->right , a);
- }
-
- void preorder(node* root , vector<int>&v){
- if(root == NULL){
- return ;
- }
- v.push_back(root->data);
- preorder(root->left , v);
- preorder(root->right , v);
- }
-
- void preorderM(node* root , vector<int>&v){
- if(root == NULL){
- return ;
- }
- v.push_back(root->data);
- preorderM(root->right , v);
- preorderM(root->left , v);
- }
-
- void postorder(node* root , vector<int>&v){
- if(root == NULL){
- return ;
- }
- postorder(root->left , v);
- postorder(root->right , v);
- v.push_back(root->data);
- }
-
- void postorderM(node* root , vector<int>&v){
- if(root == NULL){
- return ;
- }
- postorderM(root->right , v);
- postorderM(root->left , v);
- v.push_back(root->data);
- }
-
- vector<int>origin , pre , preM , post , postM;//初始, 前序 , 后序 , 平衡前序 , 平衡后序//
- int main() {
- int N , a;
- node *root = NULL;
- //输入//
- scanf("%d" , &N);
- for(int i = 0 ; i < N ; i ++) {
- scanf("%d" , &a);
- origin.push_back(a);
- insert(root , a);
- }
- //前序//
- preorder(root , pre);
- //镜像前序//
- preorderM(root , preM);
- //后序//
- postorder(root , post);
- //镜像后序//
- postorderM(root , postM);
- if(origin == pre){
- printf("YES\n");
- for(int i = 0 ; i < post.size() ; i ++) {
- if(i == post.size() - 1)
- printf("%d" , post[i]);
- else
- printf("%d " , post[i]);
- }
- }
- else if(origin == preM){
- printf("YES\n");
- for(int i = 0 ; i < postM.size() ; i ++) {
- if(i == postM.size() - 1)
- printf("%d" , postM[i]);
- else
- printf("%d " , postM[i]);
- }
- }
- else{
- printf("NO\n");
- }
- return 0;
- }
-
1045:Favorite Color Stripe(LCS)
这个题目其实LIS也是可以做的,但是我没有做。以后有时间补上。
一开始我还在想这个地方会不会有冲突出现,但是一想,LCS已经完美的解决了这个问题,关键是这个地方他有个重复的问题在里面。当前的状态如果没有匹配到的话,那就直接把前面的数值补进来。
- #include<iostream>
- using namespace std;
- const int MAXM = 205;
- const int MAXL = 10005;
-
- int a[MAXM] , b[MAXL] , dp[MAXM][MAXL];//这个要定义到外面,内部空间不够会报错.dp表示当前的最大的数值//
-
- int main(){
- int n , m , l;
- scanf("%d" , &n);
- scanf("%d" , &m);
- for(int i = 1 ; i <= m ; i ++){
- scanf("%d" , &a[i]);
- }
- scanf("%d" , &l);
- for(int i = 1 ; i <= l ; i ++){
- scanf("%d" , &b[i]);
- }
- //边界//
- for(int i = 0 ; i <= m ; i ++){
- dp[i][0] = 0;
- }
- for(int i = 0 ; i <= l ; i ++){
- dp[0][i] = 0;
- }
- //递推//
- for(int i = 1 ; i <= m ; i ++){
- for(int j = 1 ; j <= l ; j ++){
- if(a[i] == b[j]){
- dp[i][j] = max(dp[i - 1][j] , dp[i][j - 1]) + 1;
- }
- else{
- dp[i][j] = max(dp[i - 1][j] , dp[i][j - 1]);
- }
- }
- }
- printf("%d\n" , dp[m][l]);
- return 0;
- }
1047:Student List for Course(25 分)(AC)
注意要点:
1.这个地方因为不需要输入名字,所以不用hash了。
2.注意字典序的用法。
3.这个地方C的写法。二维数组换成了几个一维数组字符串。
- #include<iostream>
- #include<cstring>
- #include<vector>
- #include<algorithm>
- using namespace std;
- char C[40005][5];
- vector<int> course[40005];
-
- bool cmp(int a , int b) {
- return strcmp(C[a] , C[b]) < 0 ;//这个地方注意字典序的排列//
- }
-
- int main(){
- int N , K;
- int c , d;
- scanf("%d %d" , &N , &K);
- for(int i = 0 ; i < N ; i ++) {
- scanf("%s %d" , C[i] , &c);
- for(int j = 0 ; j < c ; j ++) {
- scanf("%d" , &d);
- course[d].push_back(i);
- }
- }
- //输出//
- for(int i = 1 ; i <= K ; i ++) {
- printf("%d %d\n" , i , course[i].size());
- sort(course[i].begin() , course[i].end() , cmp);
- for(int j = 0 ; j < course[i].size() ; j ++) {
- printf("%s\n" , C[course[i][j]]);
- }
- }
-
- return 0;
- }
1053:Path of Equal Weight (30 分)(AC)
注意要点:
1.一开始这个路径这个地方需要设置开头的点为0。
2.注意每次实现完之后都要return (因为 return 的是上一级)。
3.这个地方记录一下这个path的问题。其实path本身并不是完全记录每一条的路径。他其实就是一个再覆盖。
本身的地方在于这个输出。这个输出如果对了,就打印在他前面的所有节点的数据就可以了,而他后面的数据则不用管。
- #include<iostream>
- #include<vector>
- #include<algorithm>
- using namespace std;
-
- int N , M , S , path[105];
- struct node{
- int weight;
- vector<int> child;
- }Node[105];
-
- bool cmp(int a , int b){
- return Node[a].weight > Node[b].weight;
- }
-
- void DFS(int index , int num , int sum){
- if(sum > S) return ;//超了//
- else if(sum == S){//正好//
- if(Node[index].child.size()!= 0)
- return ;
- for(int i = 0 ; i < num ; i ++){
- if(i == num - 1)
- printf("%d\n" , Node[path[i]].weight);
- else
- printf("%d " , Node[path[i]].weight);
- }
- }
- else{//不够//
- for(int i = 0 ; i < Node[index].child.size() ; i ++){
- int c= Node[index].child[i];
- path[num] = c;//这个地方其实是直接覆盖的。
- DFS(c , num + 1 , sum + Node[c].weight);
- }
- }
- }
-
- int main(){
- scanf("%d %d %d" , &N , &M , &S);
- for(int i = 0 ; i < N ; i ++){
- scanf("%d" , &Node[i].weight);
- }
- for(int i = 0 ; i < M ; i ++){
- int id , num , a;
- scanf("%d %d" , &id , &num);
- for(int j = 0 ; j < num ; j ++){
- scanf("%d" , &a);
- Node[id].child.push_back(a);
- }
- sort(Node[id].child.begin() , Node[id].child.end() , cmp);
- }
- path[0] = 0;//把id放进来//
- DFS(0 , 1 , Node[0].weight);//起始点的位置数码 , 当前的元素的个数,当前元素的和//
- return 0;
- }
1063:Set Similarity(25 分)(AC)
注意要点:
1.注意输入的时候会出点问题,尽可能的分开输入的格式。
- #include<iostream>
- #include<set>
- using namespace std;
-
- set<int> a[55];
-
- void fun(int b , int c) {
- int samenum = 0 , allnum = a[c].size();
- for(set<int>::iterator it = a[b].begin() ; it != a[b].end() ; it ++) {
- if(a[c].find(*it) != a[c].end()) samenum ++;
- else allnum ++;
- }
- printf("%.1f%%\n" , samenum * 100.0 / allnum);
- }
-
- int main() {
- int N , n , v;
- int c , b;
- int e ;
- scanf("%d" , &N);
- for(int i = 1 ; i <= N ; i ++) {
- scanf("%d" , &n);
- for(int j = 0 ; j < n ; j ++) {
- scanf("%d" , &v);
- a[i].insert(v);
- }
- }
- //输入//
- scanf("%d" , &e);
- for(int i = 0 ; i < e ; i ++) {
- scanf("%d %d" , &b , &c);
- fun(b , c);
- }
- return 0;
- }
-
1065:A+B and C (64bit) (20)(AC)
注意要点:
1。注意 long long 的写法,范围是(2 ^ - 63 , 2 ^ 63),这个一但求和值必然会超出 long long ,只需要考虑溢出的情况即可。
2。关于溢出,这个东西就是个环形的问题 ,数字超过范围符号变化到但是数字照样加,所以会出现负数的情况。所以你也可以理解,一旦两个正数加成负数必然是溢出,到那时你c的数值必不可能会超过 long long 。与此相反,另外一面情况也可以理解了。
- #include<iostream>
- using namespace std;
- int main() {
- int N;
- int numcase = 1;
- scanf("%d" , &N);
- for(int i = 0 ; i < N ; i ++) {
- long long a , b , c;
- scanf("%lld%lld%lld", &a , &b , &c);
- long long r = a + b;
- bool flag ;
- //溢出情况检查//
- if(a > 0 && b > 0 && c < 0) flag = true;
- else if(a < 0 && b < 0 && c >= 0) flag = false;
- //正常情况检查//
- else if(r > c) flag = true;
- else flag = false;
- //输出//
- if(flag == true) {
- printf("Case #%d: true\n" , numcase ++);
- }
- else {
- printf("Case #%d: false\n" , numcase ++);
- }
- }
- return 0;
- }
1068:Find More Coins(01背包 + 记忆化搜索)
注意要点:注意01背包的含义,前i个硬币恰好有v元可以买到东西。
其次是记忆化搜索。每个状态的时候就会更新这个状态下的硬币的情况,用flag来确定每个硬币的使用情况。
- #include<iostream>
- #include<algorithm>
- #include<cstring>
- using namespace std;
- const int MAXN = 10005;
- const int MAXM = 105;
- int v[MAXN] , dp[MAXM];//dp的意思是指在前i个硬币恰好有v元能获得的价值//
- bool flag[MAXN] , choice[MAXN][MAXM];
- //在这个地方的价格和体积是一样的,所以二者合并起来了//
- bool cmp(int a , int b){//因为这个题目是一个01背包,倒着输出//
- return a > b;
- }
-
- int main(){
- memset(dp , 0 , sizeof(dp));
- int N , M;
- scanf("%d %d" , &N , &M);
- for(int i = 1 ; i <= N ; i ++){
- scanf("%d" , &v[i]);
- }
- sort(v + 1 , v + N + 1 , cmp);//从1开始的sort的写法//
- //状态转移方程//
- for(int i = 1 ; i <= N ; i ++){
- for(int V = M ; V >= v[i] ; V --){//这个地方的V已经代表了所有的情况了//
- if(dp[V] <= dp[V - v[i]] + v[i]){
- dp[V] = dp[V - v[i]] + v[i];
- choice[i][V] = 1;//使用了一枚硬币//
- }
- else choice[i][V] = 0;//没有使用一枚硬币//
- }
- }
- if(dp[M] != M){
- printf("No Solution");
- }
- else{
- //记录整个路径//
- int k = N , num = 0 , c = M;
- while(k >= 0){
-
- if(choice[k][c] == 1){//如果说第k个状态下使用了//
- flag[k] = true;//该种硬币标记为已经使用过了//
- c = c - v[k];//价值减少//
- num ++;
- }
- else{
- flag[k] = false;//没有就标记没有//
- }
- k --;//往前翻//
- }
- //输出//
- for(int i = N ; i >= 1 ; i --){
-
- if(flag[i] == true){
- printf("%d" , v[i]);
- num --;
- if(num > 0) printf(" ");
- }
- }
- }
- return 0;
- }
1069:The Black Hole of Numbers(20 分)(AC)
注意要点:
1.sort的写法.
- #include<iostream>
- #include<algorithm>
- using namespace std;
-
- int a[5] = { 0 };
-
- bool cmp(int a , int b) {
- return a > b ;
- }
-
- void isarray(int N ) {
- for(int i = 0 ; i < 4 ; i ++) {
- a[i] = N % 10;
- N /= 10;
- }
- }
-
- int isnumber(int A[]) {
- int sum = 0;
- for(int i = 0 ; i < 4 ; i ++) {
- sum = sum * 10 + a[i];
- }
- return sum;
- }
-
- int main() {
- int N , min , max;
- scanf("%d" , &N);
- while(1) {
- isarray(N);
- sort(a , a + 4);
- min = isnumber(a);//最小值//
- sort(a , a + 4 , cmp);
- max = isnumber(a); //最大值//
- N = max - min ;
- printf("%04d - %04d = %04d\n" , max , min , N);
- if(N == 0 || N == 6174) break;
- }
- return 0;
- }
1086:Tree Traversals Again (25 分)(AC)
注意要点:
1.模板题,就是一个模拟一个栈的输入和输出。
- #include<iostream>
- #include<stack>
- #include<cstring>
- using namespace std;
- const int MAX = 50;
-
- stack<int> s;
- int N;
- int pre[MAX] , in[MAX] , pos[MAX];
- struct node{
- int data;
- node* lchild;
- node* rchild;
- };
-
- node* creat(int preL , int preR , int inL , int inR){
- //范围//
- if(preL > preR)
- return NULL;
- //创建根节点//
- node* root = new node;
- root->data = pre[preL];
- //在中序遍历中找到根节点//
- int k;
- for(k = inL ; k <= inR ; k ++) {//千万注意这个地方如果前面定义了,则后面不能定义。//
- if(pre[preL] == in[k]){
- break;
- }
- }
- //切分寻找;注意技巧:左右的范围其实是对应可以接起来的。//
- int numleft = k - inL ;
- root->lchild = creat(preL + 1 , preL + numleft , inL , k - 1);
- root->rchild = creat(preL + numleft + 1 , preR , k + 1 , inR);
- return root;
- }
-
- int num = 0 ;
- void postorder(node* root) {
- if(root == NULL)
- return ;
- postorder(root->lchild);
- postorder(root->rchild);
- printf("%d" , root->data);
- num ++;
- if(num < N)
- printf(" ");
- }
-
- int main() {
- int a , preindex = 0 , inindex = 0;
- char opera[10];
- //输入操作//
- scanf("%d" , &N);
- for(int i = 0 ; i < 2 * N ; i ++) {
- scanf("%s" , opera);
- if(strcmp(opera , "Push") == 0) {
- scanf("%d" , &a);
- pre[preindex ++] = a;
- s.push(a);
- }
- else {
- in[inindex ++] = s.top();
- s.pop();
- }
- }
- //建树, 这个地方注意是有几个根的数值就补几个。//
- node* root = creat(0 , N - 1, 0 , N - 1);
- //后序遍历//
- postorder(root);
- return 0;
- }
1101:Quick Sort(25 分)(AC)
注意要点:
1.思路很清晰,但是这个地方可以利用这个小技巧,因为你每次前面的数据就是这个这个最小值了,所以完全没有必要每次都去遍历前面的数据,直接可以与上一个数据进行比较就行。
2.本题目和QS完全没有任何关系,倒像是在给你介绍QS的原理。
2.这个地方注意有个坑,最后需要输出一个回车。我其实很费解这个东西。以后建议所有的题目之后都去写一个回车以防万一。
- #include<iostream>
- #include<algorithm>
- using namespace std;
- const int INF = 1000000000;
- int main() {
- int N , sum = 0;
- int a[100005] = {0};
- int leftmax[100005] = {0};
- int rightmin[100005] = {0};
-
- //input//
- scanf("%d" , &N);
- leftmax[0] = 0;
- rightmin[N - 1] = INF;
- for(int i = 0 ; i < N ; i ++) {
- scanf("%d" , &a[i]);
- }
- //leftmax:可修正,其实完全不必每次都把数据遍历一次//
- for(int i = 1 ; i < N ; i ++) {
- leftmax[i] = max(leftmax[i - 1] , a[i - 1]);
- }
- //rightmin,这个地方你想,如果要是N - 1 的话,N - 1 + 1 不就翻出数组外头去了。。//
- for(int i = N - 2; i >= 0 ; i --) {
- rightmin[i] = min(rightmin[i + 1] , a[i + 1]);
- }
- //statistic//
- for(int i = 0 ; i < N ; i ++) {
- if(a[i] > leftmax[i] && a[i] < rightmin[i]) {
- sum ++;
- }
- }
- //output//
- printf("%d\n" , sum);
- for(int i = 0 ; i < N ; i ++) {
- if(a[i] > leftmax[i] && a[i] < rightmin[i]) {
- printf("%d" , a[i]);
- sum--;
- if(sum != 0) printf(" ");
- }
- }
- printf("\n");//无厘头的要求。//
- return 0;
- }
1107:Social Clusters(30 分)(AC)
注意要点:
1/并查集。最难的不是并查集,而是主函数。
- #include<iostream>
- #include<algorithm>
- using namespace std;
-
- int father[1005] = {0} ;
- int isroot[1005] = {0} ;
- int hobby[1005] = {0};
-
- void init(int N) {
- for(int i = 1 ; i <= N ; i ++) {
- father[i] = i;
- isroot[i] = false;
- }
- }
-
- bool cmp(int a , int b) {
- return a > b ;
- }
-
- int findfather(int x) {
- int a = x;
- while(x != father[x]) {
- x = father[x];
- }
- while(a != father[a]){
- int z = a;
- a = father[a];
- father[z] = x ;
- }
- return x;
- }
-
- void Union(int a , int b) {
- int A = findfather(a);
- int B = findfather(b);
- if(A != B) {
- father[A] = B ;
- }
- }
-
- int main() {
- int N , k , d , sum = 0;
- scanf("%d" , &N);
- init(N);
- for(int i = 1 ; i <= N ; i ++){
- scanf("%d: " , &k);
- for(int j = 0 ; j < k ; j ++) {
- scanf("%d" , &d);
- if(hobby[d] == 0) {
- hobby[d] = i;
- }
- Union(i , findfather(hobby[d]));
- }
- }
-
- for(int i = 1 ; i <= N ; i ++) {
- isroot[findfather(i)] ++;
- }
-
- for(int i = 1 ; i <= N ; i ++) {
- if(isroot[i] != 0) {
- sum ++;
- }
- }
-
- sort(isroot + 1 , isroot + N + 1 , cmp);
-
- printf("%d\n" , sum);
- for(int i = 1 ; i <= sum ; i++) {
- if(i == sum)
- printf("%d" , isroot[i]);
- else
- printf("%d " , isroot[i]);
- }
- return 0;
- }
1155. Heap Paths
解题思路:参考柳神。有的时候发现并不是不会做题,而是题目真的看不懂。。
1.利用dfs保存每条路径。(在dfs中打印数据)
2.判断大根堆和小根堆。(在大根堆中父亲节点的数据大于儿子节点的数据)
-
- #include<iostream>
- #include<vector>
- using namespace std;
-
- int n , a[1005];
- vector<int> v;
-
- void dfs(int x){
- if(2 * x > n && 2 * x + 1 > n){//×ó¸ù½ÚµãµÄÊýÖµ´óÓÚÕû¸öÊý¾Ý && ÓÒ¸ú½ÚµãµÄÊý¾Ý´óÓÚÕû¸öÊý¾Ý//
- if(x <= n){//Õâ¸ö¸ùµÄ½ÚµãûÓгöÁ˽磬µ«ÊÇÕâ¸ö¸ùµÄ½Úµã³öÁ˽磬Ôò˵Ã÷Õâ¸öµØ·½µ½ÁËÄ©¶ËÁË//
- for(int i = 0 ; i < v.size() ; i ++){//Õâ¸öµØ·½Ï൱ÓÚÊǶÔÓÚÕû¸ö·¾¶µÄÒ»¸ö±éÀú¡£
- printf("%d%s" , v[i] , i != v.size() - 1 ? " " : "\n");
- }
- }
- }
- else{
- v.push_back(a[2 * x + 1]);//ÏȽ«ÓÒ½Úµã·ÅÈ룬±éÀúÓÒ½ÚµãϵÄÊ÷//
- dfs(2 * x + 1);
- v.pop_back();
- v.push_back(a[2 * x]);//ÔÙ½«×ó½Úµã·ÅÈ룬±éÀú×ó½ÚµãϵÄÊ÷//
- dfs(2 * x);
- v.pop_back();
- }
- }
-
- int main(){
- bool ismin = false , ismax = false;
- scanf("%d" , &n);
- for(int i = 1 ; i <= n ; i ++){
- scanf("%d" , &a[i]);
- }
- v.push_back(a[1]);
- dfs(1);
- for(int i = 2 ; i <= n ; i ++){//Õâ¸öµØ·½´ÓµÚ¶þ¸ö½Úµã¿ªÊ¼,Èç¹û´ÓµÚÒ»¸ö½ÚµãÒ²¿ÉÒÔ//
- if(a[i / 2] < a[i]) ismin = true;//Èç¹û×Ó½ÚµãµÄÊýÖµ±È¸ù½ÚµãµÄÊýֵҪСµÄ»°£¬ÊÇ´ó¸ù¶Ñ//
- if(a[i / 2] > a[i]) ismax = true;//Èç¹û×Ó½ÚµãµÄÊýÖµ±È¸ù½ÚµãµÄÊýÖµÒª´óµÄ»°£¬ÔòÊÇС¸ù¶Ñ//
- }
- if(ismax == true && ismin == true){
- printf("Not Heap");
- }
- else if(ismax == true){
- printf("Max Heap");
- }
- else if(ismin == true){
- printf("Min Heap");
- }
-
- return 0;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。