力扣&PTA~每天至少三题

算法

双指针

平方数之和

https://leetcode-cn.com/problems/sum-of-square-numbers/

runtime error: signed integer overflow: 88209 + 2147395600 cannot be represented in type ‘int’

bool judgeSquareSum(int c){
    int cc=sqrt(c);
    for(int i=0;i<=cc;i++){
        for(int j=0;j<=cc;j++){
            if((i*i+j*j)==c)
            {
                return true;
            }  
            else if((i*i+j*j)>c){
                break;
            } 
        }
    }
    return false;
}

错误是i*i+j*j也是int,所以溢出了,但是我一直想的是i j都小于int c,所以不需要用long

把i和j改为long后,解决了溢出,但是超时了

class Solution {
    public boolean judgeSquareSum(int c) {
        for (long a = 0; a * a <= c; a++) {
            double b = Math.sqrt(c - a * a);
            if (b == (int) b) {
                return true;
            }
        }
        return false;
    }
}

在这里插入图片描述

167.两数之和-输入有序数组

方法一:二分查找
在数组中找到两个数,使得它们的和等于目标值,可以首先固定第一个数,然后寻找第二个数,第二个数等于目标值减去第一个数的差。利用数组的有序性质,可以通过二分查找的方法寻找第二个数。为了避免重复寻找,在寻找第二个数时,只在第一个数的右侧寻找

int* twoSum(int* numbers, int numbersSize, int target, int* returnSize) {
    int* ret = (int*)malloc(sizeof(int) * 2);
    *returnSize = 2;

    for (int i = 0; i < numbersSize; ++i) {
        int low = i + 1, high = numbersSize - 1;
        while (low <= high) {
            int mid = (high - low) / 2 + low;
            if (numbers[mid] == target - numbers[i]) {
                ret[0] = i + 1, ret[1] = mid + 1;
                return ret;
            } else if (numbers[mid] > target - numbers[i]) {
                high = mid - 1;
            } else {
                low = mid + 1;
            }
        }
    }
    ret[0] = -1, ret[1] = -1;
    return ret;
}

方法二:双指针:

int* twoSum(int* numbers, int numbersSize, int target, int* returnSize) {
    int* ret = (int*)malloc(sizeof(int) * 2);
    *returnSize = 2;

    int low = 0, high = numbersSize - 1;
    while (low < high) {
        int sum = numbers[low] + numbers[high];
        if (sum == target) {
            ret[0] = low + 1, ret[1] = high + 1;
            return ret;
        } else if (sum < target) {
            ++low;
        } else {
            --high;
        }
    }
    ret[0] = -1, ret[1] = -1;
    return ret;
}

作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/two-sum-ii-input-array-is-sorted/solution/liang-shu-zhi-he-ii-shu-ru-you-xu-shu-zu-by-leet-2/

Reverse Vowels of a string

char * reverseVowels(char * s){
    int num=strlen(s);
    int left=0,right=num;
    while(right>left){
        if(s[left]=='a'||s[left]=='e'||s[left]=='i'||s[left]=='o'||s[left]=='u'||s[left]=='A'||s[left]=='E'||s[left]=='I'||s[left]=='O'||s[left]=='U'){
            if(s[right]=='a'||s[right]=='e'||s[right]=='i'||s[right]=='o'||s[right]=='u'||s[right]=='A'||s[right]=='E'||s[right]=='I'||s[right]=='O'||s[right]=='U'){
                char tmp=s[right];
                s[right]=s[left];
                s[left]=tmp;
                right--;left++;
            }
            else{
                right--;
            }
        }
        else{
            left++;
        }
    }
    return s;
}
class Solution {
public:
    string reverseVowels(string s) {
        auto isVowel = [vowels = "aeiouAEIOU"s](char ch) {
            return vowels.find(ch) != string::npos;
        };

        int n = s.size();
        int i = 0, j = n - 1;
        while (i < j) {
            while (i < n && !isVowel(s[i])) {
                ++i;
            }
            while (j > 0 && !isVowel(s[j])) {
                --j;
            }
            if (i < j) {
                swap(s[i], s[j]);
                ++i;
                --j;
            }
        }
        return s;
    }
};


char vowel[] = "aeiouAEIOU";

bool isVowel(char ch) {
    for (int i = 0; vowel[i]; i++) {
        if (vowel[i] == ch) {
            return true;
        }
    }
    return false;
};

char* reverseVowels(char* s) {
    int n = strlen(s);
    int i = 0, j = n - 1;
    while (i < j) {
        while (i < n && !isVowel(s[i])) {
            ++i;
        }
        while (j > 0 && !isVowel(s[j])) {
            --j;
        }
        if (i < j) {
            char* tmp = s[i];
            s[i] = s[j], s[j] = tmp;
            ++i;
            --j;
        }
    }
    return s;
}

vowels = "aeiouAEIOU"s

这里到底是什么意思,我开始以为跟s这个变量有关系,想的是字符串拼接,后来想不应该呀,我把s变量都改成t发现也能过,我就知道这跟s变量没关系。后来,经过我的查找,才知道"“s是一种operator,在这里的目的是因为捕获里c++会自动推导变量类型,会把"aeiouAEIOU"推导成const char *const类型,但其实我们需要的是string类型,其实这里”"s就是转成string类型等效于vowels = std::string(“aeiouAEIOU”)

二分法

153. Find Minimum in Rotated Sorted Array

Suppose an array of length n sorted in ascending order is rotated between 1 and n times. For example, the array nums = [0,1,2,4,5,6,7] might become:

[4,5,6,7,0,1,2] if it was rotated 4 times.
[0,1,2,4,5,6,7] if it was rotated 7 times.
Notice that rotating an array [a[0], a[1], a[2], …, a[n-1]] 1 time results in the array [a[n-1], a[0], a[1], a[2], …, a[n-2]].

Given the sorted rotated array nums of unique elements, return the minimum element of this array.
You must write an algorithm that runs in O(log n) time.

public static int findMin(int[] nums) {
        int len = nums.length;
        int low = 0;
        int high = len-1;

//        二分查找
        while(low < high){
//            取中间值
            int mid = (high+low)/2;
//            如果中间值小于最大值,则最大值减小
//            疑问:为什么 high = mid;而不是 high = mid-1;
//            解答:{4,5,1,2,3},如果high=mid-1,则丢失了最小值1
            if (nums[mid] < nums[high]) {
                high = mid;
            } else {
//                如果中间值大于最大值,则最小值变大
//                疑问:为什么 low = mid+1;而不是 low = mid;
//                解答:{4,5,6,1,2,3},nums[mid]=6,low=mid+1,刚好nums[low]=1
//                继续疑问:上边的解释太牵强了,难道没有可能low=mid+1,正好错过了最小值
//                继续解答:不会错过!!! 如果nums[mid]是最小值的话,则其一定小于nums[high],走if,就不会走else了
                low = mid+1;
            }
        }
//        疑问:为什么while的条件是low<high,而不是low<=high呢
//        解答:low<high,假如最后循环到{*,10,1,*}的这种情况时,nums[low]=10,nums[high]=1,nums[mid]=10,low=mid+1,
//             直接可以跳出循环了,所以low<high,此时low指向的就是最小值的下标;
//             如果low<=high的话,low=high,还会再不必要的循环一次,此时最后一次循环的时候会发生low==high==mid,
//             则nums[mid]==nums[high],则会走一次else语句,则low=mid+1,此时low指向的是最小值的下一个下标,
//             则需要return[low-1]
        return nums[low];
    }

https://leetcode-cn.com/problems/find-minimum-in-rotated-sorted-array/solution/er-fen-cha-zhao-wei-shi-yao-zuo-you-bu-dui-cheng-z/

数据结构

链表

easy160.相交链表

  1. 双指针法:O(m+n) O(1)
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
    struct ListNode *pa=headA,*pb=headB;
    //ListNode *ta=pa.next,*tb=pb.next;
    while(pa!=pb){
        if(pa){
            pa=pa->next;
        }
        else{
            pa=headB;
        }
        if(pb){
            pb=pb->next;
        }
        else{
            pb=headA;
        }
    }
    return pa;
}
  1. 哈希集合:O(m+n) O(m)
class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        unordered_set<ListNode *> visited;
        ListNode *temp = headA;
        while (temp != nullptr) {
            visited.insert(temp);
            temp = temp->next;
        }
        temp = headB;
        while (temp != nullptr) {
            if (visited.count(temp)) {
                return temp;
            }
            temp = temp->next;
        }
        return nullptr;
    }
};

83. Remove Duplicates from Sorted List

struct ListNode* deleteDuplicates(struct ListNode* head){
    struct ListNode *tmp=head;
    while(tmp){
        if(tmp->next&&tmp->next->val==tmp->val){
            tmp->next=tmp->next->next;
        }//不同的话往后移,相同的话 比较的第一个不变,第二个后移
        else 
            tmp=tmp->next;
    }
    return head;
}

1165 Block Reversing (25 分)

Given a singly linked list L. Let us consider every K nodes as a block (if there are less than K nodes at the end of the list, the rest of the nodes are still considered as a block). Your job is to reverse all the blocks in L. For example, given L as 1→2→3→4→5→6→7→8 and K as 3, your output must be 7→8→4→5→6→1→2→3.

Input Specification:
Each input file contains one test case. For each case, the first line contains the address of the first node, a positive N (≤10
5
) which is the total number of nodes, and a positive K (≤N) which is the size of a block. The address of a node is a 5-digit nonnegative integer, and NULL is represented by −1.

Then N lines follow, each describes a node in the format:

Address Data Next
where Address is the position of the node, Data is an integer, and Next is the position of the next node.

Output Specification:
For each case, output the resulting ordered linked list. Each node occupies a line, and is printed in the same format as in the input.

Sample Input:
00100 8 3
71120 7 88666
00000 4 99999
00100 1 12309
68237 6 71120
33218 3 00000
99999 5 68237
88666 8 -1
12309 2 33218
Sample Output:
71120 7 88666
88666 8 00000
00000 4 99999
99999 5 68237
68237 6 00100
00100 1 12309
12309 2 33218
33218 3 -1

#include<bits/stdc++.h>
using namespace std;
struct node{
    int val,next;
}nodelist[100010];

int main(){
    int start,n,k;
    cin>>start>>n>>k;
    for(int i=0;i<n;i++){
        int index;
        cin>>index;
        cin>>nodelist[index].val;
        cin>>nodelist[index].next;
    }//建立链表,成功
    //链每k个
    vector<int> v;
    int p=start;
    while(p!=-1){
        v.push_back(p);
        p=nodelist[p].next;
    }
    int m=v.size();
    int r=m%k;
    int next=m-r-k;
    if(r!=0){
        for(int i=m-r;i<m;i++){
            if(i!=m-1) printf("%05d %d %05d\n",v[i],nodelist[v[i]].val,v[i+1]);
            else printf("%05d %d %05d\n",v[i],nodelist[v[i]].val,v[next]);
        }
    }
    while(next>=0){
        int now=next;
        next-=k;
        for(int i=now;i<now+k;i++){
            if(i!=now+k-1) printf("%05d %d %05d\n",v[i],nodelist[v[i]].val,v[i+1]);
            else
            {
                if(next>=0) printf("%05d %d %05d\n",v[i],nodelist[v[i]].val,v[next]);
                else printf("%05d %d -1\n",v[i],nodelist[v[i]].val);
            }
        }
    }
    return 0;
}

542.二叉树的直径
给定一棵二叉树,你需要计算它的直径长度。一棵二叉树的直径长度是任意两个结点路径长度中的最大值。这条路径可能穿过也可能不穿过根结点。
解:任意一条路径均可以被看作由某个节点为起点,从其左儿子和右儿子向下遍历的路径拼接得到

class Solution {
    int ans;
    int depth(TreeNode* rt){
        if (rt == NULL) {
            return 0; // 访问到空节点了,返回0
        }
        int L = depth(rt->left); // 左儿子为根的子树的深度
        int R = depth(rt->right); // 右儿子为根的子树的深度
        ans = max(ans, L + R + 1); // 计算d_node即L+R+1 并更新ans
        return max(L, R) + 1; // 返回该节点为根的子树的深度
    }
public:
    int diameterOfBinaryTree(TreeNode* root) {
        ans = 1;
        depth(root);
        return ans - 1;
    }
};

作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/diameter-of-binary-tree/solution/er-cha-shu-de-zhi-jing-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

感觉不用+1和-1这些操作,这样写也能通过而且容易理解点

class Solution {
    int maxd=0;
    public int diameterOfBinaryTree(TreeNode root) {
        depth(root);
        return maxd;
    }
    public int depth(TreeNode node){
        if(node==null){
            return 0;
        }
        int Left = depth(node.left);
        int Right = depth(node.right);
        maxd=Math.max(Left+Right,maxd);//将每个节点最大直径(左子树深度+右子树深度)当前最大值比较并取大者
        return Math.max(Left,Right)+1;//返回节点深度
    }
}

树的深度

递归
class Solution {
public:
    int maxDepth(TreeNode* root) {
        if (root == nullptr) return 0;
        return max(maxDepth(root->left), maxDepth(root->right)) + 1;
    }
};
BFS-队列
class Solution {
public:
    int maxDepth(TreeNode* root) {
        if (root == nullptr) return 0;
        queue<TreeNode*> Q;
        Q.push(root);
        int ans = 0;
        while (!Q.empty()) {
            int sz = Q.size();
            while (sz > 0) {
                TreeNode* node = Q.front();Q.pop();
                if (node->left) Q.push(node->left);
                if (node->right) Q.push(node->right);
                sz -= 1;
            }
            ans += 1;
        } 
        return ans;
    }
};

785.判断二分图

class Solution {
public:
    bool isBipartite(vector<vector<int>>& graph) {//graph邻接链表
        vector<int> color(graph.size(),-1);//顶点
        stack<int> color_stack;
        for(int i=0;i<graph.size();i++){
            if(color[i]==-1){
                color_stack.push(i);
                color[i]=0;

                while(!color_stack.empty()){
                    int index=color_stack.top();
                    color_stack.pop();//取栈的顶点
                    int j;
                    for(j=0;j<graph[index].size();j++){//j都在index的邻接链表上,两者相邻
                        if(color[graph[index][j]]==-1){//未涂色
                            color[graph[index][j]]=color[index]^1;//取另一种,相反的颜色
                            color_stack.push(graph[index][j]);
                        }
                        else{
                            if(color[graph[index][j]]!=color[index]^1)//不是相反,就一样
                                return false;
                        }
                    }
                }
            }
        }
        return true;
    }
};

207.course schedule 拓扑排序

There are a total of numCourses courses you have to take, labeled from 0 to numCourses - 1. You are given an array prerequisites where prerequisites[i] = [ai, bi] indicates that you must take course bi first if you want to take course ai.

For example, the pair [0, 1], indicates that to take course 0 you have to first take course 1.
Return true if you can finish all courses. Otherwise, return false.

入度+广度优先搜索+队列

684.Redundant Connection

In this problem, a tree is an undirected graph that is connected and has no cycles.

You are given a graph that started as a tree with n nodes labeled from 1 to n, with one additional edge added. The added edge has two different vertices chosen from 1 to n, and was not an edge that already existed. The graph is represented as an array edges of length n where edges[i] = [ai, bi] indicates that there is an edge between nodes ai and bi in the graph.

Return an edge that can be removed so that the resulting graph is a tree of n nodes. If there are multiple answers, return the answer that occurs last in the input.
并查集

1013 Battle Over Cities

在这里插入图片描述

不知道为啥不对

#include<bits/stdc++.h>
using namespace std;
int n,m,k;
vector<int> G[100000];//邻接表
bool vis[100000];

//需要添加的边数等于连通块的数量减1
//求连通块的数量
int currenDelPoint;
void dfs(int v){
    if(v==currenDelPoint) return;
    vis[v]=true;
    for(int i=0;i<G[v].size();i++){
        if(vis[G[v][i]]==false) dfs(G[v][i]);
    }
    
}
int main(){
    cin>>n>>m>>k;
    for(int i=0;i<m;i++){
        int a,b;
        cin>>a>>b;
        G[a].push_back(b);G[b].push_back(a);
    }
    for(int i=0;i<k;i++){
        cin>>currenDelPoint;
        memset(vis,false,sizeof(vis));
        int block=0;
        for(int j=1;j<=n;j++){
            if(j!=currenDelPoint&&vis[i]==false){
                dfs(j);//遍历顶点i所在的连通块
                block++;
            } 
        }        
        cout<<block-1<<"\n";
    }
    return 0;
}
#include<bits/stdc++.h>
using namespace std;
const int N=1010;
int n,m,k;
vector<int> G[100000];//邻接表
bool vis[100000];
int father[N];
int currenDelPoint;
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){//合并ab所在的集合
    int faA=findFather(a);
    int faB=findFather(b);
    if(faA!=faB) father[faA]=faB;
}
void init(){
    for(int i=1;i<N;i++){
        father[i]=i;
        vis[i]=false;
    }
}

int main(){
    cin>>n>>m>>k;
    for(int i=0;i<m;i++){
        int a,b;
        cin>>a>>b;
        G[a].push_back(b);G[b].push_back(a);
    }
    for(int i=0;i<k;i++){
        cin>>currenDelPoint;
        init();
        for(int j=1;j<=n;j++){//每个顶点
            for(int k=0;k<G[j].size();k++){//枚举每条边
                int u=j,v=G[j][k];//边的两个端点u v
                if(u==currenDelPoint||v==currenDelPoint) continue;
                Union(u,v);
            }
        }
        int block=0;
        for(int i=1;i<=n;i++){
            if(i==currenDelPoint) continue;
            int fa=findFather(i);//顶点i所在连通块的根节点为fa
            if(vis[fa]==false){
                block++;vis[fa]=true;
            }
        }
        cout<<block-1<<"\n";
    }
    return 0;
}

字符串stl

The above picture is from Sina Weibo, showing May 23rd, 2019 as a very cool “Prime Day”. That is, not only that the corresponding number of the date 20190523 is a prime, but all its sub-strings ended at the last digit 3 are prime numbers.

Now your job is to tell if a given date is a Prime Day.

Input Specification:
Each input file contains one test case. For each case, a date between January 1st, 0001 and December 31st, 9999 is given, in the format yyyymmdd.

Output Specification:
For each given date, output in the decreasing order of the length of the substrings, each occupies a line. In each line, print the string first, followed by a space, then Yes if it is a prime number, or No if not. If this date is a Prime Day, print in the last line All Prime!.

Sample Input 1:
20190523
Sample Output 1:
20190523 Yes
0190523 Yes
190523 Yes
90523 Yes
0523 Yes
523 Yes
23 Yes
3 Yes
All Prime!
Sample Input 2:
20191231
Sample Output 2:
20191231 Yes
0191231 Yes
191231 Yes
91231 No
1231 Yes
231 No
31 Yes
1 No
题意
判断字符串是不是素数。

满分代码
string sub2=s.substr(3,5);表示从下标3开始一直到后面5位数结束

#include<iostream>
#include<cmath>
using namespace std;
bool isPrime(int x){
    if(x==0||x==1)return false;
    if(x==2)return true;
    int y=(int)sqrt(x*1.0);
    for(int i=2;i<=y;i++){
        if(x%i==0)return false;
    }
    return true;
}
int main(){
    string s;
    cin>>s;
    bool f=true;
    for(int i=0;i<8;i++){
        string si=s.substr(i,8-i);
        int ii=stoi(si);// string to int
        cout<<si<<" ";
        if(isPrime(ii))
            cout<<"Yes"<<endl;
        else{
            cout<<"No"<<endl;
            f=false;
        }
    }
    if(f)cout<<"All Prime!";
    return 0;
}
 

————————————————
版权声明:本文为CSDN博主「浒鱼鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/allisonshing/article/details/107626283

7-2 The Judger (25分)

A game of numbers has the following rules: at the beginning, two distinct positive integers are given by the judge. Then each player in turn must give a number to the judge. The number must be the difference of two numbers that are previously given, and must not be duplicated to any of the existed numbers. The game will run for several rounds. The one who gives a duplicate number or even a wrong number will be kicked out.

Your job is to write a judger program to judge the players’ numbers and to determine the final winners.

Input Specification:
Each input file contains one test case. For each case, the first line gives two distinct positive integers to begin with. Both numbers are in [1,10​5].

In the second line, two numbers are given: N (2≤N≤10), the number of players, and M (2≤M≤10​3), the number of rounds.

Then N lines follow, each contains M positive integers. The i-th line corresponds to the i-th player (i=1,⋯,N). The game is to start from the 1st player giving his/her 1st number, followed by everybody else giving their 1st numbers in the 1st round; then everyone give their 2nd numbers in the 2nd round, and so on so forth.

Output Specification:
If the i-th player is kicked out in the k-th round, print in a line Round #k: i is out… The rest of the numbers given by the one who is out of the game will be ignored. If more than one player is out in the same round, print them in increasing order of their indices. When the game is over, print in the last line Winner(s): W1 W2 … Wn, where W1 … Wn are the indices of the winners in increasing order. All the numbers in a line must be separated by exactly one space, and there must be no extra space at the beginning or the end of the line. If there is no winner, print No winner. instead.

Sample Input 1:

101 42
4 5
59 34 67 9 7
17 9 8 50 7
25 92 43 26 37
76 51 1 41 40
1
2
3
4
5
6
Sample Output 1:

Round #4: 1 is out.
Round #5: 3 is out.
Winner(s): 2 4
1
2
3
Sample Input 2:

42 101
4 5
59 34 67 9 7
17 9 18 50 49
25 92 58 1 39
102 32 2 6 41
1
2
3
4
5
6
Sample Output 2:
Round #1: 4 is out.
Round #3: 2 is out.
Round #4: 1 is out.
Round #5: 3 is out.
No winner.

用一个哈希表来记录写的数是否在大集合中出现过,再用一个哈希表记录所有作差能得到的数,这里有个窍门,我们只要计算最后的和之前的差的绝对值,那么只要每插入一个数,就计算这个数之前的数与原先每个数的差 已经记录下来了

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;
int hash1[100000] = {0};
bool hash2[100000] = {false};

int main() {
    vector<int> a(2), win;
    int n, m, num;
    scanf("%d%d%d%d", &a[0], &a[1], &n, &m);
    hash1[a[0]] = 1;
    hash1[a[1]] = 1;
    vector<int> v[n], flag(n, 0);
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            scanf("%d", &num);
            v[i].push_back(num);
        }
    }
    for (int j = 0; j < m; j++) {
        vector<int> out;
        for (int i = 0; i < n; i++) {
            if (flag[i])continue;
            for (int k = a.size() - 2; k >= 0; k--)
                hash2[abs(a[a.size() - 1] - a[k])] = true;
            if (hash1[v[i][j]] == 0 && hash2[v[i][j]]) {
                a.push_back(v[i][j]);
                hash1[v[i][j]] = 1;
            } else {
                flag[i] = true;
                out.push_back(i + 1);
            }
        }
        if (!out.empty()) {
            for (int k = 0; k < out.size(); k++)
                printf("Round #%d: %d is out.\n", j + 1, out[k]);
        }
    }
    for (int i = 0; i < n; i++)
        if (!flag[i])win.push_back(i + 1);
    if (win.empty())printf("No winner.");
    else {
        printf("Winner(s):");
        for (int i = 0; i < win.size(); i++)printf(" %d", win[i]);
    }
    return 0;
}

1132 Cut Integer (20 分)

Cutting an integer means to cut a K digits lone integer Z into two integers of (K/2) digits long integers A and B. For example, after cutting Z = 167334, we have A = 167 and B = 334. It is interesting to see that Z can be devided by the product of A and B, as 167334 / (167 × 334) = 3. Given an integer Z, you are supposed to test if it is such an integer.

Input Specification:
Each input file contains one test case. For each case, the first line gives a positive integer N (≤ 20). Then N lines follow, each gives an integer Z (10 ≤ Z <2
31
). It is guaranteed that the number of digits of Z is an even number.

Output Specification:
For each case, print a single line Yes if it is such a number, or No if not.
错误版本:terminate called after throwing an instance of ‘std::invalid_argument’ what(): stoi

#include<bits/stdc++.h>
using namespace std;
int main(){
    int n;
    //scanf("%d",&n);
    cin>>n;
    string s;
    for(int i=0;i<n;i++){
        //scanf("%s",s);
        getline(cin,s);
        cout<<s;
        int m=stoi(s);
        cout<<m;
        int len=s.length();
        string s1,s2;
        s2=s.substr(len/2);
        s1=s.substr(0,len/2);
        int m1=stoi(s1);
        int m2=stoi(s2);
        if(m%(m1*m2)==0) printf("Yes\n");
        else printf("No\n");
    }
    return 0;
}

m%(m1*m2)==0&&m1*m2!=0错,要注意a*b如果为0的时候不能取余,否则会浮点错误~

#include<bits/stdc++.h>
using namespace std;
int main(){
    int n;
    //scanf("%d",&n);
    cin>>n;
    string s;
    for(int i=0;i<n;i++){
        int m;
        scanf("%d",&m);
        string s=to_string(m);
        int len=s.length();
        string s1,s2;
        s2=s.substr(len/2);
        s1=s.substr(0,len/2);
        int m1=stoi(s1);
        int m2=stoi(s2);
        if(m1*m2!=0&&m%(m1*m2)==0) printf("Yes\n");
        else printf("No\n");
    }
    return 0;
}

1133 Splitting A Linked List (25 分)

Given a singly linked list, you are supposed to rearrange its elements so that all the negative values appear before all of the non-negatives, and all the values in [0, K] appear before all those greater than K. The order of the elements inside each class must not be changed. For example, given the list being 18→7→-4→0→5→-6→10→11→-2 and K being 10, you must output -4→-6→-2→7→0→5→10→18→11.

Sample Input:
00100 9 10
23333 10 27777
00000 0 99999
00100 18 12309
68237 -6 23333
33218 -4 00000
48652 -2 -1
99999 5 68237
27777 11 48652
12309 7 33218
Sample Output:
33218 -4 68237
68237 -6 48652
48652 -2 12309
12309 7 00000
00000 0 99999
99999 5 23333
23333 10 00100
00100 18 27777
27777 11 -1

#include <iostream>
#include <vector>
using namespace std;
struct node {
    int id, data, next;
};
int main() {
    int begin, n, k, s, d, e;
    scanf("%d%d%d", &begin, &n, &k);
    node a[100010];
    vector<node> v, ans;
    for (int i = 0; i < n; i++) {
        scanf("%d%d%d", &s, &d, &e);
        a[s] = {s, d, e};
    }
    for (; begin != -1; begin = a[begin].next)
        v.push_back(a[begin]);
    for (int i = 0; i < v.size(); i++)
        if (v[i].data < 0) ans.push_back(v[i]);
    for (int i = 0; i < v.size(); i++)
        if (v[i].data >= 0 && v[i].data <= k) ans.push_back(v[i]);
    for (int i = 0; i < v.size(); i++)
        if (v[i].data > k) ans.push_back(v[i]);
    for (int i = 0; i < ans.size() - 1; i++)
        printf("%05d %d %05d\n", ans[i].id, ans[i].data, ans[i + 1].id);
    printf("%05d %d -1\n", ans[ans.size() - 1].id, ans[ans.size() - 1].data);
    return 0;
}

1134. Vertex Cover (25)-PAT甲级真题

string当成数字相加

string太长了,stoi stod不行

#include <iostream>
#include <algorithm>
using namespace std;
string rev(string s) {
    reverse(s.begin(), s.end());
    return s;
}
string add(string s1, string s2) {
    string s = s1;
    int carry = 0;
    for (int i = s1.size() - 1; i >= 0; i--) {
        s[i] = (s1[i] - '0' + s2[i] - '0' + carry) % 10 + '0';
        carry = (s1[i] - '0' + s2[i] - '0' + carry) / 10;
    }
    if (carry > 0) s = "1" + s;
    return s;
}
int main() {
    string s, sum;
    int n = 10;
    cin >> s;
    if (s == rev(s)) {
        cout << s << " is a palindromic number.\n";
        return 0;
    }
    while (n--) {
        sum = add(s, rev(s));
        cout << s << " + " << rev(s) << " = " << sum << endl;
        if (sum == rev(sum)) {
            cout << sum << " is a palindromic number.\n";
            return 0;
        }
        s = sum;
    }
    cout << "Not found in 10 iterations.\n";
    return 0;
}

1157 Anniversary (25 分)

Zhejiang University is about to celebrate her 122th anniversary in 2019. To prepare for the celebration, the alumni association (校友会) has gathered the ID’s of all her alumni. Now your job is to write a program to count the number of alumni among all the people who come to the celebration.

Input Specification:
Each input file contains one test case. For each case, the first part is about the information of all the alumni. Given in the first line is a positive integer N Then N lines follow, each contains an ID number of an alumnus. An ID number is a string of 18 digits or the letter X. It is guaranteed that all the ID’s are distinct.
The next part gives the information of all the people who come to the celebration. Again given in the first line is a positive integer M . Then M lines follow, each contains an ID number of a guest. It is guaranteed that all the ID’s are distinct.

Output Specification:
First print in a line the number of alumni among all the people who come to the celebration. Then in the second line, print the ID of the oldest alumnus – notice that the 7th - 14th digits of the ID gives one’s birth date. If no alumnus comes, output the ID of the oldest guest instead. It is guaranteed that such an alumnus or guest is unique.

Sample Input:
5
372928196906118710
610481197806202213
440684198612150417
13072819571002001X
150702193604190912
6
530125197901260019
150702193604190912
220221196701020034
610481197806202213
440684198612150417
370205198709275042
Sample Output:
3
150702193604190912
set.find找元素,而不是遍历;在遍历的过程中通过比较得到最值,不是sort
vector:std::sort(a.begin(),a.end(),cmp);

#include <bits/stdc++.h>
using namespace std;
set<string> s;
bool cmp(string a, string b)
{
    return stoi(a.substr(6, 8)) < stoi(b.substr(6, 8));
}
int main()
{
    int n, m;
    cin >> n;
    for (int i = 0; i < n; i++)
    {
        string tmp;
        cin >> tmp;
        s.insert(tmp);
    }
    cin >> m;

    int numm = 0, f = 0;
    string tmp, oldd, apldd;
    int old = 99999999, aold;
    aold = old;
    apldd = oldd;
    for (int i = 0; i < m; i++)
    {
        cin >> tmp;

        if (s.find(tmp) != s.end())
        {
            numm++;
            int it = stoi(tmp.substr(6, 8));
            if (old > it)
            {
                old = it;
                oldd = tmp;
                f = 1;
                continue;
            }
        }

        int it = stoi(tmp.substr(6, 8));
        if (aold > it)
        {
            apldd = tmp;
            aold = it;
        }
    }

    if (!numm)
    {
        printf("%d\n", numm);
        cout << apldd;
    }
    else
    {
        printf("%d\n", numm);
        cout << oldd;
    }
    return 0;
}

dfs加剪枝

1160 Forever (20 分)

“Forever number” is a positive integer A with K digits, satisfying the following constrains:

the sum of all the digits of A is m;
the sum of all the digits of A+1 is n; and
the greatest common divisor of m and n is a prime number which is greater than 2.
Now you are supposed to find these forever numbers.

Input Specification:
Each input file contains one test case. For each test case, the first line contains a positive integer N (≤5). Then N lines follow, each gives a pair of K (3<K<10) and m (1<m<90), of which the meanings are given in the problem description.

Output Specification:
For each pair of K and m, first print in a line Case X, where X is the case index (starts from 1). Then print n and A in the following line. The numbers must be separated by a space. If the solution is not unique, output in the ascending order of n. If still not unique, output in the ascending order of A. If there is no solution, output No Solution.

Sample Input:
2
6 45
7 80
Sample Output:
Case 1
10 189999
10 279999
10 369999
10 459999
10 549999
10 639999
10 729999
10 819999
10 909999
Case 2
No Solution

#include<bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef pair<int,ll> PIL;
int k,m,flag;
PIL a[10010];

int gcd(int x,int y){
    return y==0 ? x:gcd(y,x%y);
}
int isprime(int x){
    if(x<=1) return 0;
    for(int i=2;i<=x/i;i++)
        if(x%i==0) return 0;
    return 1;
}

void dfs(int cnt,int sum,ll x){//cnt位数,sum各位和,x串
    if(cnt>k||sum>m||m>sum+9*(k-cnt)) return;//结束 不成功的边界条件;m太大了,剩余位全为9还大
    if(cnt==k&&sum==m){
        ll y=x+1;
        int n=0;
        while (y)
        {
            n+=(y%10);y/=10;
        }
        if(gcd(n,m)>2&&isprime(gcd(n,m)))
        {
            a[flag++]={n,x};return;
        }                   
    }
    for(int i=0;i<=9;i++)
        if(sum==0&&i==0) continue;
        else dfs(cnt+1,sum+i,x*10+i);
}
int main(){
    int t;
    scanf("%d",&t);
    for(int i=1;i<=t;i++){
        printf("Case %d\n",i);
        flag=0;
        scanf("%d%d",&k,&m);
        dfs(0,0,0);
        if(!flag) printf("No Solution\n");
        else{
            sort(a,a+flag);
            for(int i=0;i<flag;i++)
                printf("%d %lld\n",a[i].first,a[i].second);
        }
    }
    return 0;
}

1153 Decode Registration Card of PAT (25 分)

A registration card number of PAT consists of 4 parts:

the 1st letter represents the test level, namely, T for the top level, A for advance and B for basic;
the 2nd - 4th digits are the test site number, ranged from 101 to 999;
the 5th - 10th digits give the test date, in the form of yymmdd;
finally the 11th - 13th digits are the testee’s number, ranged from 000 to 999.
Now given a set of registration card numbers and the scores of the card owners, you are supposed to output the various statistics according to the given queries.

Input Specification:
Each input file contains one test case. For each case, the first line gives two positive integers N (≤10
4
) and M (≤100), the numbers of cards and the queries, respectively.

Then N lines follow, each gives a card number and the owner’s score (integer in [0,100]), separated by a space.

After the info of testees, there are M lines, each gives a query in the format Type Term, where

Type being 1 means to output all the testees on a given level, in non-increasing order of their scores. The corresponding Term will be the letter which specifies the level;
Type being 2 means to output the total number of testees together with their total scores in a given site. The corresponding Term will then be the site number;
Type being 3 means to output the total number of testees of every site for a given test date. The corresponding Term will then be the date, given in the same format as in the registration card.
Output Specification:
For each query, first print in a line Case #: input, where # is the index of the query case, starting from 1; and input is a copy of the corresponding input query. Then output as requested:

for a type 1 query, the output format is the same as in input, that is, CardNumber Score. If there is a tie of the scores, output in increasing alphabetical order of their card numbers (uniqueness of the card numbers is guaranteed);
for a type 2 query, output in the format Nt Ns where Nt is the total number of testees and Ns is their total score;
for a type 3 query, output in the format Site Nt where Site is the site number and Nt is the total number of testees at Site. The output must be in non-increasing order of Nt’s, or in increasing order of site numbers if there is a tie of Nt.
If the result of a query is empty, simply print NA.

Sample Input:
8 4
B123180908127 99
B102180908003 86
A112180318002 98
T107150310127 62
A107180908108 100
T123180908010 78
B112160918035 88
A107180908021 98
1 A
2 107
3 180908
2 999
Sample Output:
Case 1: 1 A
A107180908108 100
A107180908021 98
A112180318002 98
Case 2: 2 107
3 260
Case 3: 3 180908
107 2
123 2
102 1
Case 4: 2 999
NA
两个小样例过不去:Case 3: 3 00001,考场号读进来再输出要补0
printf("Case %d: %d %06d",i+1,ty,t3);cout<<"\n";

#include <iostream>
#include <vector>
#include <unordered_map>
#include <algorithm>
using namespace std;
struct node {
    string t;
    int value;
};
bool cmp(const node &a, const node &b) {
    return a.value != b.value ? a.value > b.value : a.t < b.t;
}
int main() {
    int n, k, num;
    string s;
    cin >> n >> k;
    vector<node> v(n);
    for (int i = 0; i < n; i++)
        cin >> v[i].t >> v[i].value;
    for (int i = 1; i <= k; i++) {
        cin >> num >> s;
        printf("Case %d: %d %s\n", i, num, s.c_str());
        vector<node> ans;
        int cnt = 0, sum = 0;
        if (num == 1) {
            for (int j = 0; j < n; j++)
                if (v[j].t[0] == s[0]) ans.push_back(v[j]);
        } else if (num == 2) {
            for (int j = 0; j < n; j++) {
                if (v[j].t.substr(1, 3) == s) {
                    cnt++;
                    sum += v[j].value;
                }
            }
            if (cnt != 0) printf("%d %d\n", cnt, sum);
        } else if (num == 3) {
            unordered_map<string, int> m;
            for (int j = 0; j < n; j++)
                if (v[j].t.substr(4, 6) == s) m[v[j].t.substr(1, 3)]++;
            for (auto it : m) ans.push_back({it.first, it.second});
        }
        sort(ans.begin(), ans.end(),cmp);
        for (int j = 0; j < ans.size(); j++)
            printf("%s %d\n", ans[j].t.c_str(), ans[j].value);
        if (((num == 1 || num == 3) && ans.size() == 0) || (num == 2 && cnt == 0)) printf("NA\n");
    }
    return 0;
}
#include<bits/stdc++.h>
using namespace std;
struct node{
    string s;
    int d;
}a[100000];
struct n3{
    int id,c;
}bb[1000];
bool cmp(node a,node b){
    if(a.d != b.d){
        return a.d>b.d;
    }
    return a.s<b.s;
}
bool cmp1(n3 a,n3 b){
    if(a.c != b.c){
        return a.c>b.c;
    }
    return a.id<b.id;
}
int main(){
    int n,m;
    cin>>n>>m;
    for(int i=0;i<n;i++){
        cin>>a[i].s;
        scanf("%d",&a[i].d);
    }
    for(int i=0;i<m;i++){
        int ty,f=0;
        string tp;
        cin>>ty;
        if(ty==1){
            cin>>tp;f=0;
            printf("Case %d: %d ",i+1,ty);cout<<tp<<"\n";
            sort(a,a+n,cmp);
            for(int j=0;j<n;j++){
                if(a[j].s.substr(0,1)==tp){
                    cout<<a[j].s<<" "<<a[j].d<<"\n";f=1;              
                }
            }
        }
        else if(ty==2){
            int t2,f=0;
            cin>>t2;
            printf("Case %d: %d ",i+1,ty);cout<<t2<<"\n";
            int sum=0,num=0;
            for(int j=0;j<n;j++){
                if(stoi(a[j].s.substr(1,3))==t2){
                    sum+=a[j].d;num++;f=1;                                  
                }
            }
            if(f) {
                cout<<num<<" "<<sum<<"\n";continue;
            }
        }
        else{
            int t3,f=0,k=0;
            cin>>t3;
            int b[1000]={0};
            for(int j=0;j<n;j++){
                if(stoi(a[j].s.substr(4,6))==t3){
                    b[stoi(a[j].s.substr(1,3))]++;
                }
            }
            printf("Case %d: %d %06d",i+1,ty,t3);cout<<"\n";
            for(int j=100;j<=999;j++){
                if(b[j]) {
                    //printf("%d %d\n",j,b[j]);f=1;
                    bb[k].id=j;bb[k].c=b[j];k++;
                }
            }
            sort(bb,bb+k,cmp1);
            for(int kk=0;kk<k;kk++){
                printf("%d %d\n",bb[kk].id,bb[kk].c);f=1;
            }
            if(f) continue;
        }
        if(!f) printf("NA\n");
    }
    return 0;
}

不会map写的复杂了

1148 Werewolf - Simple Version (20 分)

Werewolf(狼人杀) is a game in which the players are partitioned into two parties: the werewolves and the human beings. Suppose that in a game,

player #1 said: “Player #2 is a werewolf.”;
player #2 said: “Player #3 is a human.”;
player #3 said: “Player #4 is a werewolf.”;
player #4 said: “Player #5 is a human.”; and
player #5 said: “Player #4 is a human.”.
Given that there were 2 werewolves among them, at least one but not all the werewolves were lying, and there were exactly 2 liars. Can you point out the werewolves?

Now you are asked to solve a harder version of this problem: given that there were N players, with 2 werewolves among them, at least one but not all the werewolves were lying, and there were exactly 2 liars. You are supposed to point out the werewolves.

Input Specification:
Each input file contains one test case. For each case, the first line gives a positive integer N (5≤N≤100). Then N lines follow and the i-th line gives the statement of the i-th player (1≤i≤N), which is represented by the index of the player with a positive sign for a human and a negative sign for a werewolf.

Output Specification:
If a solution exists, print in a line in ascending order the indices of the two werewolves. The numbers must be separated by exactly one space with no extra spaces at the beginning or the end of the line. If there are more than one solution, you must output the smallest solution sequence – that is, for two sequences A=a[1],…,a[M] and B=b[1],…,b[M], if there exists 0≤k<M such that a[i]=b[i] (i≤k) and a[k+1]<b[k+1], then A is said to be smaller than B. In case there is no solution, simply print No Solution.

Sample Input 1:
5
-2
+3
-4
+5
+4
Sample Output 1:
1 4
首先要会写出来伪代码

#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
int main() {
    int n;
    cin >> n;
    vector<int> v(n+1);
    for (int i = 1; i <= n; i++) cin >> v[i];
    for (int i = 1; i <= n; i++) {
        for (int j = i + 1; j <= n; j++) {
            vector<int> lie, a(n + 1, 1);//假设ij为lier,这样每次初始化,其实在遍历
            a[i] = a[j] = -1;
            for (int k = 1; k <= n; k++)
                if (v[k] * a[abs(v[k])] < 0) lie.push_back(k);
            if (lie.size() == 2 && a[lie[0]] + a[lie[1]] == 0) {
                cout << i << " " << j;
                return 0;
            }
        }
    }
    cout << "No Solution";
    return 0;
}
#include<iostream>
#include<vector>
using namespace std;
struct node{
	int id, dat, next;	
};
int main(){
	int beg1, beg2, n1, m, n;
	scanf("%d %d %d", &beg1, &beg2, &n1);
	node a[100010];
	vector<node> v1, v2, ans;
	int s, d, e;
	for(int i=0; i<n1; i++){
		scanf("%d%d%d",&s,&d,&e);
		a[s]={s,d,e};
	}
	for(; beg1!=-1; beg1=a[beg1].next){
		v1.push_back(a[beg1]);
	}
	for(; beg2!=-1; beg2=a[beg2].next){
		v2.push_back(a[beg2]);
	}
	m=v1.size(), n=v2.size();
	if(m<n){ //要特别注意边界,多出的数的处理
		int t=0;
		for(int i=0; i<m; i++){
			int a=2*i;
			if(a<n) {
				ans.push_back(v2[a]);
				t++;
			}
			if(a+1<n) {
				ans.push_back(v2[a+1]);
				t++;
			}
			ans.push_back(v1[m-i-1]);
		}
		for(; t<n; t++) ans.push_back(v2[t]);
	}else{
		int t=0;
		for(int i=0; i<n; i++){
			int a=2*i;
			if(a<m) {
				ans.push_back(v1[a]);
				t++;
			}
			if(a+1<m) {
				ans.push_back(v1[a+1]);
				t++;
			}
			ans.push_back(v2[m-i-1]);
		}
		for(; t<m; t++) ans.push_back(v1[t]);
	}
	int i;
	for(i=0; i<ans.size()-1; i++){
		printf("%05d %d %05d\n", ans[i].id, ans[i].dat, ans[i+1].id);
	}
	printf("%05d %d -1\n", ans[i].id, ans[i].dat);
	return 0;
}

树图

1162 Postfix Expression (25 分)

Given a syntax tree (binary), you are supposed to output the corresponding postfix expression, with parentheses reflecting the precedences of the operators.

Input Specification:
Each input file contains one test case. For each case, the first line gives a positive integer N (≤ 20) which is the total number of nodes in the syntax tree. Then N lines follow, each gives the information of a node (the i-th line corresponds to the i-th node) in the format:

data left_child right_child
where data is a string of no more than 10 characters, left_child and right_child are the indices of this node’s left and right children, respectively. The nodes are indexed from 1 to N. The NULL link is represented by −1. The figures 1 and 2 correspond to the samples 1 and 2, respectively.

Output Specification:
For each case, print in a line the postfix expression, with parentheses reflecting the precedences of the operators.There must be no space between any symbols.

Sample Input 1:

8
* 8 7
a -1 -1
* 4 1
+ 2 5
b -1 -1
d -1 -1
- -1 6
c -1 -1

Sample Output 1:
(((a)(b)+)(©(-(d))))
Sample Input 2:

 8
 2.35 -1 -1
 * 6 1
 - -1 4 % 7 8
 + 2 3 a -1 -1 str -1 -1 871 -1 -1

Sample Output 2:
(((a)(2.35)*)(-((str)(871)%))+)

1134. Vertex Cover (25)-PAT甲级真题

A vertex cover of a graph is a set of vertices such that each edge of the graph is incident to at least one vertex of the set. Now given a graph with several vertex sets, you are supposed to tell if each of them is a vertex cover or not.

Input Specification:

Each input file contains one test case. For each case, the first line gives two positive integers N and M (both no more than 104), being the total numbers of vertices and the edges, respectively. Then M lines follow, each describes an edge by giving the indices (from 0 to N-1) of the two ends of the edge.

After the graph, a positive integer K (<= 100) is given, which is the number of queries. Then K lines of queries follow, each in the format:

Nv v[1] v[2] … v[Nv]

where Nv is the number of vertices in the set, and v[i]’s are the indices of the vertices.

Output Specification:

For each query, print in a line “Yes” if the set is a vertex cover, or “No” if not.

Sample Input:
10 11
8 7
6 8
4 5
8 4
8 1
1 2
1 4
9 8
9 1
1 0
2 4
5
4 0 3 8 4
6 6 1 7 5 4 9
3 1 8 4
2 2 8
7 9 8 7 6 5 4 2
Sample Output:
No
Yes
Yes
No
No

题目大意:给n个结点m条边,再给k个集合。对这k个集合逐个进行判断。每个集合S里面的数字都是结点编号,求问整个图所有的m条边两端的结点,是否至少一个结点出自集合S中。如果是,输出Yes否则输出No

分析:用vector v[n]保存某结点属于的某条边的编号,比如a b两个结点构成的这条边的编号为0,则v[a].push_back(0),v[b].push_back(0)——表示a属于0号边,b也属于0号边。对于每一个集合做判断,遍历集合中的每一个元素,将当前元素能够属于的边的编号i对应的hash[i]标记为1,表示这条边是满足有一个结点出自集合S中的。最后判断hash数组中的每一个值是否都是1,如果有不是1的,说明这条边的两端结点没有一个出自集合S中,则输出No。否则输出Yes~

#include <iostream>
#include <vector>
using namespace std;
int main() {
    int n, m, k, nv, a, b, num;
    scanf("%d%d", &n, &m);
    vector<int> v[n];
    for (int i = 0;i < m; i++) {
        scanf("%d%d", &a, &b);
        v[a].push_back(i);
        v[b].push_back(i);
    }
    scanf("%d", &k);
    for (int i = 0; i < k; i++) {
        scanf("%d", &nv);
        int flag = 0;
        vector<int> hash(m, 0);
        for (int j = 0; j < nv; j++) {
            scanf("%d", &num);
            for (int t = 0; t < v[num].size(); t++)
                hash[v[num][t]] = 1;
        }
        for (int j = 0; j < m; j++) {
            if (hash[j] == 0) {
                printf("No\n");
                flag = 1;
                break;
            }
        }
        if (flag == 0) printf("Yes\n");
    }
    return 0;
}

1158 Telefraud Detection (25 分)

Telefraud(电信诈骗) remains a common and persistent problem in our society. In some cases, unsuspecting victims lose their entire life savings. To stop this crime, you are supposed to write a program to detect those suspects from a huge amount of phone call records.

A person must be detected as a suspect if he/she makes more than K short phone calls to different people everyday, but no more than 20% of these people would call back. And more, if two suspects are calling each other, we say they might belong to the same gang. A makes a short phone call to B means that the total duration of the calls from A to B is no more than 5 minutes.

Input Specification:
Each input file contains one test case. For each case, the first line gives 3 positive integers K (≤500, the threshold(阈值) of the amount of short phone calls), N (≤10
3
, the number of different phone numbers), and M (≤10
5
, the number of phone call records). Then M lines of one day’s records are given, each in the format:

caller receiver duration
where caller and receiver are numbered from 1 to N, and duration is no more than 1440 minutes in a day.

Output Specification:
Print in each line all the detected suspects in a gang, in ascending order of their numbers. The gangs are printed in ascending order of their first members. The numbers in a line must be separated by exactly 1 space, and there must be no extra space at the beginning or the end of the line.

If no one is detected, output None instead.

Sample Input 1:
5 15 31
1 4 2
1 5 2
1 5 4
1 7 5
1 8 3
1 9 1
1 6 5
1 15 2
1 15 5
3 2 2
3 5 15
3 13 1
3 12 1
3 14 1
3 10 2
3 11 5
5 2 1
5 3 10
5 1 1
5 7 2
5 6 1
5 13 4
5 15 1
11 10 5
12 14 1
6 1 1
6 9 2
6 10 5
6 11 2
6 12 1
6 13 1
Sample Output 1:
3 5
6
Note: In sample 1, although 1 had 9 records, but there were 7 distinct receivers, among which 5 and 15 both had conversations lasted more than 5 minutes in total. Hence 1 had made 5 short phone calls and didn’t exceed the threshold 5, and therefore is not a suspect.

#define MAX 1005
#define INF 14400
int tu[MAX][MAX],K,M,N;//将通话时长累加 作为两点之间的距离
bool vis[MAX]={0};
vector<int>out;
set<int>gan;
void visit(int v)//用来找团伙的,用set.clear()清空
{
    vis[v]=1;gan.insert(v);
    for(int i=0;i<out.size();++i){
        if(vis[out[i]]==0&&tu[v][out[i]]<INF&&tu[out[i]][v]<INF)visit(out[i]);
    }
}
int main()
{
    //freopen("test.txt","r",stdin);
    scanf("%d%d%d",&K,&N,&M);
    int c,r,d;
    for(int i=1;i<=N;++i){
        for(int j=1;j<=N;++j){
            tu[i][j]=INF;
        }
    }
    while(M--){
        scanf("%d%d%d",&c,&r,&d);
        if(tu[c][r]==INF)tu[c][r]=d;
        else tu[c][r]+=d;
    }
    for(int i=1;i<=N;++i){
        int cnt=0,x=0;
        for(int j=1;j<=N;++j){
            if(tu[i][j]<=5){
              ++cnt;
              if(tu[j][i]!=INF)++x;
            }
        }
        if(cnt>K&&x<=cnt/5)out.push_back(i);
    }
    if(out.size()==0){
        printf("None");
        return 0;
    }
    sort(out.begin(),out.end());
    //for(int i=0;i<out.size();++i)printf("%d ",out[i]);printf("\n");
    for(int i=0;i<out.size();++i){
        if(!vis[out[i]]){
            gan.clear();
            visit(out[i]);
            set<int>::iterator it=gan.begin();
            while(it!=gan.end()){
                if(it!=gan.begin())printf(" ");
                printf("%d",*it);
                ++it;
            }
            printf("\n");
        }
    }
    return 0;
}

PAT Judge
在struct里多声明几个变量,清楚?8

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct node {
    int rank, id, total = 0;
    vector<int> score;
    int passnum = 0;
    bool isshown = false;
};
bool cmp1(node a, node b) {
    if(a.total != b.total)
        return a.total > b.total;
    else if(a.passnum != b.passnum)
        return a.passnum > b.passnum;
    else
        return a.id < b.id;
}

int main() {
    int n, k, m, id, num, score;
    scanf("%d %d %d", &n, &k, &m);
    vector<node> v(n + 1);
    for(int i = 1; i <= n; i++)
        v[i].score.resize(k + 1, -1);
    vector<int> full(k + 1);
    for(int i = 1; i <= k; i++)
        scanf("%d", &full[i]);
    for(int i = 0; i < m; i++) {
        scanf("%d %d %d", &id, &num, &score);
        v[id].id = id;
        v[id].score[num] = max(v[id].score[num], score);
        if(score != -1)
            v[id].isshown = true;
        else if(v[id].score[num] == -1)
            v[id].score[num] = -2;
    }
    for(int i = 1; i <= n; i++) {
        for(int j = 1; j <= k; j++) {
            if(v[i].score[j] != -1 && v[i].score[j] != -2)
                v[i].total += v[i].score[j];
            if(v[i].score[j] == full[j])
                v[i].passnum++;
        }
    }
    sort(v.begin() + 1, v.end(), cmp1);
    for(int i = 1; i <= n; i++) {
        v[i].rank = i;
        if(i != 1 && v[i].total == v[i - 1].total)
            v[i].rank = v[i - 1].rank;
    }
    for(int i = 1; i <= n; i++) {
        if(v[i].isshown == true) {
            printf("%d %05d %d", v[i].rank, v[i].id, v[i].total);
            for(int j = 1; j <= k; j++) {
                if(v[i].score[j] != -1 && v[i].score[j] != -2)
                    printf(" %d", v[i].score[j]);
                else if(v[i].score[j] == -1)
                    printf(" -");
                else
                    printf(" 0");
            }
            printf("\n");
        }
    }
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值