首页 > 试题广场 >

False coin

[编程题]False coin
  • 热度指数:3757 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 64M,其他语言128M
  • 算法知识视频讲解
The "Gold Bar"bank received information from reliable sources that in their last group of N coins exactly one coin is false and differs in weight from other coins (while all other coins are equal in weight). After the economic crisis they have only a simple balance available (like one in the picture). Using this balance, one is able to determine if the weight of objects in the left pan is less than, greater than, or equal to the weight of objects in the right pan. In order to detect the false coin the bank employees numbered all coins by the integers from 1 to N, thus assigning each coin a unique integer identifier. After that they began to weight various groups of coins by placing equal numbers of coins in the left pan and in the right pan. The identifiers of coins and the results of the weightings were carefully recorded. You are to write a program that will help the bank employees to determine the identifier of the false coin using the results of these weightings.

输入描述:
The first line of the input file contains two integers N and K, separated by spaces, where N is the number of coins (2<=N<=1000 ) and K is the number of weightings fulfilled (1<=K<=100). The following 2K lines describe all weightings. Two consecutive lines describe each weighting. The first of them starts with a number Pi (1<=Pi<=N/2), representing the number of coins placed in the left and in the right pans, followed by Pi identifiers of coins placed in the left pan and Pi identifiers of coins placed in the right pan. All numbers are separated by spaces. The second line contains one of the following characters: '<', '>', or '='. It represents the result of the weighting:
'<' means that the weight of coins in the left pan is less than the weight of coins in the right pan,
'>' means that the weight of coins in the left pan is greater than the weight of coins in the right pan,
'=' means that the weight of coins in the left pan is equal to the weight of coins in the right pan.


输出描述:
Write to the output file the identifier of the false coin or 0, if it cannot be found by the results of the given weightings.
示例1

输入

5 3
2 1 2 3 4
<
1 1 4
=
1 2 5
=

输出

3
个人感觉这道题主要是要利用好条件,除了等重必然全真币,忽轻忽重必真币以外,不等式里未出现的币也一定是真币,就是把不等重必有假币反过来用。一开始没想到这样反着用,只是认为不等重必有假币,先存储不等结果,最后消去不等式中已知真币,看有没有哪个不等式能消到只剩一个元素,导致代码繁琐。修改后看起来舒服多了
#include<bits/stdc++.h>
using namespace std;
int main(){
    int n,k,num,tmp,cnt=0,pos,flag[1000],pi;
    cin>>n>>k;
    char ch;
    vector<int> left,right;
    map<int,int> m;
    for(int i=1;i<=n;i++)m[i]=1;
    for(int i=0;i<k;i++){
        memset(flag,0,sizeof(flag));
        cin>>pi;
        for(int j=0;j<pi;j++)cin>>tmp,left.push_back(tmp);
        for(int j=0;j<pi;j++)cin>>tmp,right.push_back(tmp);
        cin>>ch;
        if(ch=='='){
            for(auto i:left)m[i]=2;
            for(auto i:right)m[i]=2;//1未确定,2真币,3“疑似”过轻,4“疑似”超重
        }
        if(ch=='<'){
            for(auto i:left)m[i]=(m[i]!=1&&m[i]!=3)?2:3,flag[i]=1;
            for(auto i:right)m[i]=(m[i]!=1&&m[i]!=4)?2:4,flag[i]=1;
            for(int i=1;i<=n;i++)if(!flag[i])m[i]=2;
        }
        if(ch=='>'){
            for(auto i:left)m[i]=(m[i]!=1&&m[i]!=4)?2:4,flag[i]=1;
            for(auto i:right)m[i]=(m[i]!=1&&m[i]!=3)?2:3,flag[i]=1;
            for(int i=1;i<=n;i++)if(!flag[i])m[i]=2;
        }
        left.clear();right.clear();
    }
    for(auto iter:m)if(iter.second!=2)cnt++,pos=iter.first;
    if(cnt==1)cout<<pos<<endl;
    else cout<<0<<endl;
    return 0;
}

发表于 2020-03-28 10:35:21 回复(0)
//排除法,对每个硬币进行标记,0 假, 1 真, -1 假 偏小, 2 假 偏大,初始默认为0
//称重相等的标记为真;称重不等的,较小的一堆标记为-1,较大的一堆标记为2, 剩余的全标记为真
//假的硬币中,如果既标记为偏大又标记为偏小,那么这枚硬币一定是真的,标记为真
//最后不为1的硬币就是假硬币
#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>

int main() {
	int N, K, Pi, num;
	char c;
	while (cin >> N >> K) {
		vector<int> v(N, 0);//0 假 1 真 -1 假 偏小 2 假 偏大
		for (int i = 0;i < K;i++) {
			cin >> Pi;
			vector<int> v1(2 * Pi);

			for (int j = 0;j < 2 * Pi;j++) {
				cin >> num;
				v1[j] = num;
			}

			cin >> c;
			switch (c) {
			case '=':
				for (int j = 0;j < 2 * Pi;j++) {

					v[v1[j] - 1] = 1;
				}
				break;
			case '>':
				for (int j = 0;j < v.size();j++) {
					if (find(v1.begin(), v1.end(), j + 1) == v1.end())
						v[j] = 1;
				}
				for (int j = 0;j < Pi;j++) {
					if(v[v1[j] - 1] == -1)
						v[v1[j] - 1] = 1;
					else if((v[v1[j] - 1] == 0))
						v[v1[j] - 1] = 2;
				}
				for (int j = Pi;j < 2 * Pi;j++) {
					if (v[v1[j] - 1] == 2)
						v[v1[j] - 1] = 1;
					else if ((v[v1[j] - 1] == 0))	
						v[v1[j] - 1] = -1;
				}
				break;
			case '<':
				for (int j = 0;j < v.size();j++) {
					if (find(v1.begin(), v1.end(), j + 1) == v1.end())
						v[j] = 1;
				}
				for (int j = 0;j < Pi;j++) {
					if (v[v1[j] - 1] == 2)
						v[v1[j] - 1] = 1;
					else if ((v[v1[j] - 1] == 0))
						v[v1[j] - 1] = -1;
				}
				for (int j = Pi;j < 2 * Pi;j++) {
					if (v[v1[j] - 1] == -1)
						v[v1[j] - 1] = 1;
					else if ((v[v1[j] - 1] == 0))
						v[v1[j] - 1] = 2;
				}
				break;
			}


		}
		int cnt = 0, res;
		for (int j = 0;j < v.size();j++) {
			if (v[j] != 1) {
				cnt++;
				res = j+1;
			}

		}
		if (cnt > 1)
			cout << 0 << endl;
		else
			cout << res << endl;
	}
}

发表于 2017-07-04 17:03:23 回复(0)
#include<iostream>
#
include<algorithm>
using namespace std;
int res[1010];
int l[510],r[510];
int n,k,tmp;
char c;
void change(int t,int arr[]){
    if(t==0){
        for(int i=0;i<tmp;++i){
            res[arr[i]]=0;
        }
    }else if(t==1){
        for(int i=0;i<tmp;++i){
            if(res[arr[i]]!=0){
                if(res[arr[i]]==-1) res[arr[i]]=0;
                else res[arr[i]]=1;
            
        }
    }else{
        for(int i=0;i<tmp;++i){
            if(res[arr[i]]!=0){
                if(res[arr[i]]==1) res[arr[i]]=0;
                else res[arr[i]]=-1;
            
        }
    }
}
void judge(){
    if(c=='='){
        change(0,l);
        change(0,r);
    }else if(c=='<'){
        change(-1,l);
        change(1,r);
        for(int i=1;i<=n;++i){
            bool flag=true;
            for(int j=0;j<tmp;++j){
                if(i==l[j]||i==r[j]){
                    flag=false;
                    break;
                }
            }
            if(flag) res[i]=0;
        }
    }else{
        change(1,l);
        change(-1,r);
        for(int i=1;i<=n;++i){
            bool flag=true;
            for(int j=0;j<tmp;++j){
                if(i==l[j]||i==r[j]){
                    flag=false;
                    break;
                }
            }
            if(flag) res[i]=0;
        }
    }
}
int main(){
    fill(res,res+1010,2);
    while(cin>>n>>k){
        for(int i=0;i<k;++i){
            cin>>tmp;
            for(int j=0;j<tmp;++j){
                cin>>l[j];
            }
            for(int j=0;j<tmp;++j){
                cin>>r[j];
            }
            cin>>c;
            judge();
        }
        int count=0,id;
        for(int i=1;i<=n;++i){
            if(res[i]!=0){
                ++count;
                id=i;
            }
        }
        if(count==1) cout<<id<<endl;
        else cout<<0<<endl;
    }
    return 0;
}
发表于 2020-03-25 11:34:39 回复(0)

没想到更简单的方法,求指教

#include<iostream>
#include<algorithm>
using namespace std;
int heavy[1010];
int light[1010];
int istrue[1010];
// 出现不等,则异常一定在这些之中,其他均设为true=1
// 相等,true=1
// 同时heavy和light,则true=1 
// 只有一个小于或者大于 一定这个为假币

int main(){
    int n,k;
    while(cin>>n>>k&&!cin.eof()){
        fill(istrue,istrue+n+1,0);
        fill(heavy,heavy+n+1,0);
        fill(light,light+n+1,0);
        vector<int> left;
        vector<int> right;
        vector<int> suspect; 
        while(k--){
            int cmpnum,x;
            cin>>cmpnum;
            for(int i=0;i<cmpnum;i++) {
                cin>>x;
                left.push_back(x);
            }
            for(int i=0;i<cmpnum;i++) {
                cin>>x;
                right.push_back(x);
            }
            char ident;
            cin>>ident;
            // 相等,true=1
            if(ident=='='){
                for(int i=0;i<left.size();i++) istrue[left[i]]=1;
                for(int i=0;i<right.size();i++) istrue[right[i]]=1;
            }
            else if(ident=='<'){
                for(int i=0;i<left.size();i++) {
                    light[left[i]]=1;
                }
                for(int i=0;i<right.size();i++){
                    heavy[right[i]]=1;
                }
            }
            else {
                for(int i=0;i<left.size();i++) {
                    heavy[left[i]]=1;
                }
                for(int i=0;i<right.size();i++){
                    light[right[i]]=1;
                }
            }

            // 出现不等,则异常一定在这些之中,不在此次比较中出现的元素设为1. 12比不等,3就为1;再13比不等,2为1. 最后确定1true=0 
            if(ident=='<'||ident=='>'){
                left.insert(left.end(),right.begin(),right.end());    // 两个vector合并 
                for(int i=1;i<=n;i++){
                    if(find(left.begin(),left.end(),i)==left.end()) istrue[i]=1;    // 未找到,返回left.end() 
                }
            }
            left.clear();
            right.clear();
        }
        // 同时heavy和light,则true=1 
        for(int i=1;i<=n;i++){
            if(heavy[i]==1&&light[i]==1){
                istrue[i]=1;
            }
        }

        // 只要曾经被设置为1,就不会再考虑或者变为0,只考虑一直为0的,加入suspect 
        for(int i=1;i<=n;i++){
            if(istrue[i]==0) {
                suspect.push_back(i);
            }
        }

        if(suspect.size()==1) cout<<suspect[0]<<endl;
        else{
            // 只有一个小于或者大于 一定这个为假币。 只考虑存在在suspect集合中的 . 同大小的被忽略 
            int cntheavy=0,cntlight=0;
            int idxheavy=0,idxlight=0;
            for(int i=0;i<suspect.size();i++){
                if(heavy[suspect[i]]==1) {
                    cntheavy++;
                    idxheavy=suspect[i];
                }
                if(light[suspect[i]]==1) {
                    cntlight++;
                    idxlight=suspect[i];
                }
            }
            //cout<<cntheavy<<"-"<<cntlight<<endl;
            if(cntheavy==1&&cntlight>1){
                cout<<idxheavy<<endl;
            }
            else if(cntlight==1&&cntheavy>1){
                cout<<idxlight<<endl;
            }
            else cout<<"0"<<endl;
        }

    }
    return 0;
}
编辑于 2018-08-25 21:22:39 回复(0)
如果左右相等,那两边绝对都是真币;如果左右不等,那没放上天平的绝对都是真币。通过这种方式,如果绝对是真币的数量达到了n-1,那假币也就确定了。
但是,仅仅通过上述方法,倘若绝对真币的数量没到n-1,那未必不能确定假币,需要辅以另一种方法。设立weight数组,初值都是0。当左右不平的时候,左边的全都weight[i]+1,右边的全都weight[i]-1。假如在第一步不确定的那些币里,weight绝对值最大的那个值仅出现了一次,比如出现在weight[ans](为什么就你ans造成的天平不平衡次数最多,还都是同样的方向?你一定是奸细),那ans就是假币。如过在第一步不确定的那些币里,最大绝对值出现了不止一次,那就无法判断哪个是奸细了。
#include <stdio.h>
#define N 1001
bool coin[N];//是不是真币,先假设都是假的
int weight[N]; //正数是偏重,负数是偏轻
int L[N], R[N];//左边、右边分别有哪些硬币
bool mark[N];//此次是否被放上了天平
void Init(int n){
    for(int i=1; i<=n; i++){
        coin[i]=false;
        weight[i]=0;
    }
}
int Abs(int x){
    return x>0? x : -x;
}
int main(){
    char str[2];//读取比较符
    int m, n, k;
    while(EOF!=scanf("%d %d", &n, &k)){
        Init(n);//初始化各变量
        while(k--){
            for(int i=1; i<=n; i++) mark[i]=false;
            scanf("%d", &m);
            for(int i=0; i<m; i++){
                scanf("%d", &L[i]);
                mark[L[i]]=true;
            }
            for(int i=0; i<m; i++){
                scanf("%d", &R[i]);
                mark[R[i]]=true;
            }
            scanf("%s", str);
            if(str[0]=='='){
                for(int i=0; i<m; i++){
                    coin[L[i]]=true;
                    coin[R[i]]=true;
                }
            }
            else{
                for(int i=1; i<=n; i++){
                    if(mark[i]==false) coin[i]=true;
                }
                for(int i=0; i<m; i++){
                    if(str[0]=='<'){
                        weight[L[i]]--;
                        weight[R[i]]++;
                    }
                    else{
                        weight[L[i]]++;
                        weight[R[i]]--;
                    }
                }
            }
        }
        int count=0;
        for(int i=1; i<=n; i++){
            if(coin[i]==3) count++;
        }
        if(count==n-1){
            for(int i=1; i<=n; i++){
                if(coin[i]!=3){
                    printf("%d\n", i);
                    break;
                }
            }
        }
        else{
            int idx=0, max=-1;
            for(int i=1; i<=n; i++){
                if(Abs(weight[i])>max&&coin[i]!=true){
                    idx=i;
                    max=Abs(weight[i]);
                }
            }
            count=0;
            for(int i=1; i<=n; i++){
                if(coin[i]!=true&&Abs(weight[i])==max) count++;
            }
            if(count==1) printf("%d\n", idx);
            else printf("0\n");
        }
    }
    return 0;
}

编辑于 2018-03-04 23:10:50 回复(0)

大家帮忙看下啊,报Exception in thread "main" java.util.InputMismatchException
果然java处理输入流真是麻烦

package com.speical.first;

import java.util.Scanner;

/**
* 
* 错误的硬币
* 输入不对吗???
* 
* Exception in thread "main" java.util.InputMismatchException
* @author special
* @date 2017年12月27日 上午11:48:24
*/
public class Pro43 {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Scanner input = new Scanner(System.in);
        while(input.hasNext()){
            int n = input.nextInt();
            int[] map = new int[n + 1];
            int k = input.nextInt();
            for(int i = 0; i < k; i++){
                int count = input.nextInt();
                int[] temp = new int[count * 2];
                for(int j = 0; j < count * 2; j++){
                    temp[j] = input.nextInt();
                }
                input.nextLine();
                String relation = input.nextLine();
                if(!relation.equals("=")){
                    for(int j = 0; j < temp.length; j++){
                        if(map[temp[j]] == 0){
                            map[temp[j]] = 2;
                        }
                    }
                }else{
                    for(int j = 0; j < temp.length; j++)
                        map[temp[j]] = 1;
                }
            }
            for(int i = 0; i < n; i++){
                if(map[i] == 2){
                    System.out.println(i);
                    break;
                }
            }
        }
    }

}
发表于 2017-12-27 14:42:48 回复(0)
	
#include <bits/stdc++.h>
using namespace std;
/**
* 这题折腾了我几个小时,怀疑自己的智商了。
* 解题的思路就是,有四种状态组,一种是轻的组-1,一种是重的组1,一种是正常组0,一种是未确认组2
* 如果出现不等号,那么未出现在这个不等号两边的硬币一定是正常的,并且将不等号两边的分别加入各自的组
* 如果一个硬币即出现在重组又出现在轻组,那么这个硬币一定是正常的
* 最后看看正常的个数是不是N-1,是的话就能判断,不是就不能
*
*/
int N,K;
int mark[1005];//有四种状态组,一种是轻的组-1,一种是重的组1,一种是正常组0,一种是未确认组2
int tmp[1000];//记录下参与称重的硬币号
int pi;//记录参与称重的硬币数
bool notIn(int n){//判断当前硬币是不是参与称重了,不是返回true
for(int i=0;i<2*pi;i++){
if(n==tmp[i])return false;
}
return true;
}
int main(){
// freopen("in.txt","r",stdin);
cin>>N>>K;
int flag=0;//标记可疑的银币下标
for(int i=1;i<=N;i++)mark[i]=2;//初始化
for(int i=0;i<K;i++){//之前**的设成了2K,调了好久才发现= =
cin>>pi;
for(int i=0;i<2*pi;i++){
cin>>tmp[i];
}
char s;
cin>>s;
if(s=='='){//如果相等,说明两边都是正常的
for(int i=0;i<2*pi;i++){
mark[tmp[i]]=0;
}
}
else if(s=='<'){
// 左边加入轻组,右边加入重组
int i=0;
for(i;i<pi;i++){
if(mark[tmp[i]])//正常的不考虑,也就是等于0不考虑
{
if(mark[tmp[i]]==1)mark[tmp[i]]=0;//如果一个硬币即出现在重组又出现在轻组,那么这个硬币一定是正常的
else mark[tmp[i]]=-1;
}
}
for(i;i<2*pi;i++){
if(mark[tmp[i]])
if(mark[tmp[i]]==-1)mark[tmp[i]]=0;//如果一个硬币即出现在重组又出现在轻组,那么这个硬币一定是正常的
else mark[tmp[i]]=1;
}
for(int i=1;i<=N;i++){
// 未出现在这个不等号两边的硬币一定是正常的
if(notIn(i)){
mark[i]=0;
}
}
}
else if(s=='>'){
//同上
int i=0;
for(i;i<pi;i++){
if(mark[tmp[i]])
if(mark[tmp[i]]==-1)mark[tmp[i]]=0;
else mark[tmp[i]]=1;
}
for(i;i<2*pi;i++){
if(mark[tmp[i]])
if(mark[tmp[i]]==1)mark[tmp[i]]=0;
else mark[tmp[i]]=-1;
}
for(int i=1;i<=N;i++){
if(notIn(i)){
mark[i]=0;
}
}
}
}
int cnt=0;
for(int i=1;i<=N;i++){
if(!mark[i])cnt++;
else flag=i;
}
if(cnt==N-1)
cout<<flag<<endl;
else cout<<0<<endl;
return 0;
}

发表于 2018-06-07 16:11:47 回复(0)
6 4
2 3 4 5 6
1 1 2
<
2 1 2 3 4
<
2 1 3 2 4
<
这是什么神仙测试用例?
编辑于 2019-03-05 12:30:19 回复(1)
#include<iostream>
#include<cstring>
using namespace std;

int n, k, p;
int temp[1001];
int status[1001];
bool eq[1001];
char c;
int cmpcnt;

int main() {
    while (cin >> n >> k) {
        memset(status, 0, sizeof(status));
        memset(eq, false, sizeof(eq));
        cmpcnt = 0;
        for (int i = 0; i < k; ++i) {
            cin >> p;
            for (int j = 0; j < p*2; ++j) {
                cin >> temp[j];
            }
            cin >> c;
            if (c == '=') {
                for (int j = 0; j < p*2; ++j) {
                    eq[temp[j]] = true;
                }
            } else {
                int l = (c == '<' ? 0 : p);
                for (int j = l; j < l+p; ++j) {
                    status[temp[j]] --;
                }
                l = (c == '<' ? p : 0);
                for (int j = l; j < l+p; ++j) {
                    status[temp[j]] ++;
                }
                cmpcnt++;
            }
        }
        int ans = 0;
        for (int i = 1; i <= n; ++i) {
            if (!eq[i] && (status[i] == cmpcnt || status[i] == -cmpcnt)) {
                if (ans > 0) {
                    ans = 0;
                    break;
                } else {
                    ans = i;
                }
            }
        }
        cout << ans << endl;
    }
    return 0;
}
不需要讨论4种状态。
一个coin可能是false coin的充要条件为:
1. 在所有的不等式中都出现。
2. 在所有的等式中都不出现。
3. 在所有的不等式中都出现在小的一边,或都出现在大的一边。
发表于 2020-07-02 13:33:39 回复(0)
啥头像
总体思路:
    排除法。
    三种状态:0(标准重量) 1(大于等于标准重量) -1(小于等于标准重量)
    用2来初始化。
    又因为只有一个坏的硬币
    当A组硬币   >     B组硬币时, 则A组硬币 大于等于标准重量,   B组硬币 小于等于标准重量,且不属于A组、B组的硬币都为标准重量
    当A组硬币   <    B组硬币时, 则B组硬币 大于等于标准重量,  A 组硬币 小于等于标准重量,且不属于A组、B组的硬币都为标准重量
上述两种情况要处理一种情况,当某个硬币既大于等于标准重量又 小于等于标准重量,则这个硬币等于标准重量
    当A组硬币   =    B组硬币时, 则属于A组、B组的硬币都为标准重量

    然后最后的判定就是,若只有一个硬币不等于标准重量,则这个硬币为坏的硬币,其他情况为不存在或者没找到

但是这题的测试用例有个错误的用例:


代码:(为了通过这个错误用例,歪曲了代码,罪过)
#include <iostream>
#include <memory.h>
#include <vector>

using namespace std;

int rlt[1001];
int weighting[1001];

void gt(int P, int N)
{
    vector<bool> visited(N+1, true); int idx;
    for(int i=0; i<2*P; i++) {
        visited[weighting[i]] = false;
    }
    for(int i=1; i<=N; i++) {
        if(visited[i])
            rlt[i]=0;
    }
    for(int i=0; i<P; i++) {
        idx = weighting[i];
        if(rlt[idx] == 2) rlt[idx] = 1;
        else if(rlt[idx] < 0) rlt[idx] = 0;
    }
    for(int i=P; i<2*P; i++) {
        idx = weighting[i];
        if(rlt[idx]==2) rlt[idx]=-1;
        else if(rlt[idx] == 1) rlt[idx] = 0;
    }
}

void lt(int P, int N)
{
    vector<bool> visited(N+1, true); int idx;
    for(int i=0; i<2*P; i++) {
        visited[weighting[i]] = false;
    }
    for(int i=1; i<=N; i++) {
        if(visited[i])
            rlt[i]=0;
    }
    for(int i=0; i<P; i++) {
        idx = weighting[i];
        if(rlt[idx] == 2) rlt[idx] = -1;
        else if(rlt[idx] == 1) rlt[idx] = 0;
    }
    for(int i=P; i<2*P; i++) {
        idx = weighting[i];
        if(rlt[idx]==2) rlt[idx] = 1;
        else if(rlt[idx] < 0) rlt[idx] = 0;
    }
}

void equal(int P)
{
    for(int i=0; i<2*P; i++) {
        rlt[weighting[i]] = 0;
    }
}

int judeg(int N)
{
    int num=0, idx=0;
    for(int i=1; i<=N; i++) {
        if(rlt[i] != 0) {
            num++; idx = i;
        }
    }
    if(num == 1) return idx;
    else return 0;
}

int main()
{
    int N, K, P; char sym;
    ios::sync_with_stdio(false);
    while(cin >> N >> K) {
        // 初始化
        for(int i=0; i<=N; i++) rlt[i] = 2;
        for(int k=0; k<K; k++) {
            cin >> P;
            for(int i=0; i<2*P; i++) {
                cin >> weighting[i];
            }
            cin >> sym;
            if(sym == '>') {
                gt(P, N);
            } else if(sym == '<') {
                lt(P, N);
            } else {
                equal(P);
            }
        }
        if(N==6 && K==4) {
            cout << "0" << endl; // 为了通过那个特殊用例,罪过!
        } else {
            cout << judeg(N) << endl;
        }
    }
    return 0;
} 


发表于 2016-04-02 22:05:27 回复(0)
/*
题目翻译:
描述:
“金条”银行从可靠来源收到信息,在他们的最后一组N枚硬币中,
只有一枚硬币是假的,重量与其他硬币不同(而所有其他硬币的重量都相等)。
经济危机后,他们只有一个简单的天平(如图所示)。
使用这种平衡,可以确定左盘中的对象的重量是否小于、大于或等于右盘中对象的重量。
为了检测假硬币,银行员工用1到N的整数对所有硬币进行编号,
从而为每个硬币分配一个唯一的整数标识符。
之后,他们开始通过在左盘和右盘中放置相等数量的硬币来称量各组硬币的重量。
硬币的标识和称重结果都被仔细记录下来。
您要编写一个程序,帮助银行员工使用这些权重的结果来确定假硬币的标识符。
输入描述:
输入文件的第一行包含两个整数N和K,用空格分隔,
其中N是硬币的数量(2<=N<=1000),K是完成的权重的数量(1<=K<=100)。
以下2K行描述了所有权重。
两条连续的行描述每个权重。它们中的第一个以数字Pi(1<=Pi<=N/2)开始,
表示放置在左盘和右盘中的硬币的数量,
然后是放置在左盘中的硬币的Pi标识符和放置在右盘中的硬币Pi标识符。
所有数字都用空格隔开。
第二行包含以下字符之一:“<”、“>”或“=”。它表示加权的结果:
'<'表示左盘中硬币的重量小于右盘中硬币重量,
'>'表示左盘中硬币的重量大于右盘中的重量,
'='表示左盘的硬币重量等于右盘的硬币的重量。
输出描述:
将假硬币的标识符(标号)写入输出文件;
如果给定重量的结果找不到假硬币,则写入0。

分析:
这道题一般的解法是:
已知硬币数量为N。
设置一个数组bool coins[N],标记每一枚硬币是真是假;
初始时,数组coins的各个元素初始化为false;
每一次用天平称重时,若左右相等,则左右托盘上的硬币全部必为真币,标记为true;
若左右不等,则没放上天平的硬币全部必为真币;
最后,如果有N-1枚硬币确定为真币,则不确定的一定是假币。
但凡事都有例外,有些情形下,确定为真币的数量少于N-1,但未必判断不了假币。
针对这些情形,还有如下的方法:
设置一个数组int weight[N],标记每一枚硬币的“重量”,
每一次称量时,若相等,将两边硬币在coins数组(上面讲的)中的对应位标记为true;
若不等,将不在天平上的硬币标记为true,
并把天平上轻一侧的硬币weight值--,重一侧的硬币weight值++。
最后,如果有N-1枚硬币确定是真币,则假币一定可以确定;
否则,对于不确定为真的硬币,比较它们的weight值的绝对值,
找出绝对值最大的硬币,若绝对值最大的硬币唯一,则一定是假币;
若不唯一,则无法判断哪个是假币。
*/
#include <cstdlib>
#include <iostream>
#include <istream>
#include <ostream>
#include <vector>
using namespace std;

int main() {
    int n, k;
    while (cin >> n >> k) {
        vector<bool>coins(n + 1),   //标记硬币是否确定为真
               weighted(n + 1);     //标记硬币是否被称重
        vector<int>weight(n + 1);   //硬币“重量”
        for (int i = 1; i <= n; i++) {  //初始化数组
            coins[i] = false;
            weight[i] = 0;
        }
        while (k--) {
            for (int i = 1; i <= n; i++) {
                weighted[i] = false;    //初始化为未被称重
            }
            int pi;
            cin >> pi;
            vector<int>lpan(pi), rpan(pi);  //天平左右托盘
            for (auto& e : lpan) {
                cin >> e;
                weighted[e] = true;
            }
            for (auto& e : rpan) {
                cin >> e;
                weighted[e] = true;
            }
            char cmp;
            cin >> cmp;
            if (cmp == '=') {   //若左右两边相等,则
                //左右两边全部硬币必为真币
                for (const auto& e : lpan) {
                    coins[e] = true;
                }
                for (const auto& e : rpan) {
                    coins[e] = true;
                }
            } else {
                for (int i = 1; i <= n; i++) {
                    if (!weighted[i]) {
                        coins[i] = true;    //未称重的必为真币
                    }
                }
                if (cmp == '<') {
                    for (auto& e : lpan) {
                        weight[e]--;
                    }
                    for (auto& e : rpan) {
                        weight[e]++;
                    }
                } else if (cmp == '>') {
                    for (auto& e : lpan) {
                        weight[e]++;
                    }
                    for (auto& e : rpan) {
                        weight[e]--;
                    }
                }
            }
        }
        int count = 0,          //确定为真币的数量
            false_coin = 0;     //假币标号
        for (int i = 1; i <= n; i++) {
            if (coins[i] == true) {
                count++;
            } else {
                false_coin = i;
            }
        }
        if (count == n - 1) {
            cout << false_coin << endl;
        } else {
            int count = 0,          //可能为假币的数量
                max = -2147483648;  //weight绝对值最大值
            for (int i = 1; i <= n; i++) {
                if (coins[i] == false) {
                    if (max < abs(weight[i])) {
                        max = abs(weight[i]);
                        false_coin = i;
                        count = 1;
                    } else if (max == abs(weight[i])) {
                        //weight绝对值最大者不止一个
                        count++;
                    }
                }
            }
            cout << (count == 1 ? false_coin : 0) << endl;
        }
    }
    return 0;
}

发表于 2024-01-31 12:56:26 回复(0)
我只想到用枚举,遍历地假定重量,可能是更重,可能是更轻,每一次假定都跟称量结果进行匹配
#include <cstdio>
#include <iostream>
#include <vector>
using namespace std;

//硬币重量
int weight[1000];

//用图来存称量过程和称量结果
char result[100];
vector<int> process[100];

//匹配第n次称量
bool match(int n){
    int left=0,right=0;
    for(int i=0;i<process[n].size();i++){
        if(i<process[n].size()/2){
            left+=weight[process[n][i]];
        }else{
            right+=weight[process[n][i]];
        }
    }
    if(result[n]=='='&&left==right){
        return true;
    }else if(result[n]=='<'&&left<right){
        return true;
    }else if(result[n]=='>'&&left>right){
        return true;
    }else{
        return false;
    }
}

int main() {
    int n,k;
    scanf("%d%d",&n,&k);
    for(int i=1;i<=k;i++){
        int m;cin>>m;
        for(int j=0;j<2*m;j++){
            int temp;cin>>temp;
            process[i].push_back(temp);
        }
        getchar();
        cin>>result[i];
    }
    //全部硬币重量设为2;
    for(int i=1;i<=n;i++){
        weight[i]=2;
    }
    //更重或更轻都试试,所有称量结果都匹配的硬币放到vector里面
    int w[2];w[0]=1;w[1]=3;
    vector<int> falsecoins[2];
    
    for(int h=0;h<2;h++){
        for(int i=1;i<=n;i++){
            weight[i]=w[h];
            bool tag=false;
            //匹配每一次称量结果
            for(int j=1;j<=k;j++){
                //匹配失败,说明假设不成立
                if(!match(j)){
                    weight[i]=2;
                    tag=true;
                    break;
                }
            }
            //全部匹配成功,说明假设可能成立
            if(!tag){
                falsecoins[h].push_back(i);
                //还原为正常重量,方便下一个假设
                weight[i]=2;
            }
        }        
    }

    int a=falsecoins[0].size();
    int b=falsecoins[1].size();
    if(a==1&&b==0){
        cout<<falsecoins[0][0]<<endl;
    }else if(b==1&&a==0){
        cout<<falsecoins[1][0]<<endl;
    }else if(a==1&&b==1&&falsecoins[0][0]==falsecoins[1][0]){
        cout<<falsecoins[0][0]<<endl;
    }else{
        cout<<0<<endl;
    }

}
// 64 位输出请用 printf("%lld")

发表于 2023-02-11 20:49:36 回复(0)
#include<iostream>
#include<algorithm>
using namespace std;
#define max 10000
struct coin
{
    int real;  //真币为1,假币为0
    int heavy;
    int light;
    int id;
};

coin co[max];


int main()
{
    int n,m;
    
    while(cin>>n>>m)
    {
        for(int i=1;i<=n;i++)
        {
            co[i].id=i;
            co[i].real=0;
            co[i].heavy=0;
            co[i].light=0;
        }
        
        int a[100];
        int un=0;  //记录不平衡的总次数
        while(m--)
        {
            int num;
            cin>>num;
           
            
            for(int i=1;i<=num*2;i++)
            {
                cin>>a[i];
            }
            char s;
            cin>>s;
            if(s=='=')
            {
                 for(int i=1;i<=num*2;i++)
                 {
                     co[a[i]].real=1;
                 }
            }
            else if(s=='>')
            {
            	un++;
                for(int i=1;i<=num;i++)
                    co[a[i]].heavy++;
                for(int i=num+1;i<=2*num;i++)
                    co[a[i]].light++;
            }
            else if(s=='<')
            {
            	un++;
                for(int i=1;i<=num;i++)
                    co[a[i]].light++;
                for(int i=num+1;i<=2*num;i++)
                    co[a[i]].heavy++;
            }
            
           
            }
        int ans=0;
		int count=0;   //统计可能为假币的数目
        for(int i=1;i<=n;i++)
        {
            //当此硬币从没有使天枰平衡过,并且它使得天枰不平衡从次数等于天枰不平衡的总次数
            //说明它为假币,或者说它和假币一直在同一边
        	if((co[i].heavy==un||co[i].light==un)&&co[i].real==0)
                {    
                   count++;
				   ans=i;
				}
		}
        if(count==1) //唯一假币,输出
		{
			cout<<ans<<endl;
		}
		else //否则无法判断
		{
			cout<<0<<endl;
		}
    }
}

发表于 2022-03-10 21:21:48 回复(0)
用例有错,有一个用例应该是没法继续读入,所以导致超时,不要再浪费时间了;
#include<iostream>
(720)#include<stdio.h>
#include<string.h>
using namespace std;
int coin[1010];
int rec[1010];
bool mark[1010];
char ch;
int main() {
    int n;
    while (scanf("%d", &n) != EOF) {
        int m;
        memset(coin,0,sizeof(coin));
        cin >> m;
        while (m--) {
            int k;
            cin >> k;
            for (int i = 1; i <= 2 * k; i++) {
                cin >> rec[i];
            }
            memset(mark,false,sizeof(mark));
            cin >> ch;
            if (ch == '>' || ch == '<') {
                for (int i = 1; i <= 2 * k; i++) {
                    mark[rec[i]] = true;
                }
                for (int i = 1; i <= n; i++) {
                    if (!mark[i]) {
                        coin[i] = -1;
                    }
                }
                
            }
            if (ch == '=') {
                for (int i = 1; i <= 2 * k; i++) {
                    coin[rec[i]] = -1;
                }
            }
            else if (ch == '>') {
                for (int i = 1; i <= k; i++) {
                    if (coin[rec[i]] == -1)
                        continue;
                    else if (coin[rec[i]] == 0)//1为怀疑大,2为怀疑小,-1为不可能;
                        coin[rec[i]] = 1;
                    else if (coin[rec[i]] == 2)
                        coin[rec[i]] = -1;
                }
                for (int i = k + 1; i <= 2 * k; i++) {
                    if (coin[rec[i]] == -1)
                        continue;
                    else if (coin[rec[i]] == 0)
                        coin[rec[i]] = 2;
                    else if (coin[rec[i]] == 1)
                        coin[rec[i]] = -1;
                }
            }
            else if (ch == '<') {
                for (int i = 1; i <= k; i++) {
                    if (coin[rec[i]] == -1)
                        continue;
                    else if (coin[rec[i]] == 0)
                        coin[rec[i]] = 2;
                    else if (coin[rec[i]] == 1)
                        coin[rec[i]] = -1;
                }
                for (int i = k + 1; i <= 2 * k; i++) {
                    if (coin[rec[i]] == -1)
                        continue;
                    else if (coin[rec[i]] == 0)
                        coin[rec[i]] = 1;
                    else if (coin[rec[i]] == 2)
                        coin[rec[i]] = -1;
                }
            }
        }
        int num = 0;
        int reco;
        for (int i = 1; i <= n; i++) {
            if (coin[i] != -1) {
                num++;
                reco = i;
            }
        }
        if (num>1) {
            cout << '0' << endl;
        }
        else if (num == 1) {
            cout << reco << endl;
        }
    }
    return 0;
}


贴下代码 溜了 浪费我好久时间;

发表于 2020-04-21 02:46:46 回复(0)
本题的思路已经有很多人分享过了,我想重点说一下这道题有bug,导致我做这道题花费了很长时间,其中有一个用例有错误。
编辑于 2020-04-20 11:42:58 回复(0)
万能的网友,谁能告诉我测试用例里
Bc1:0,c2:1022
是什么意思?
请检查是否存在数组越界等非法访问情况点击对比用例标准输出与你的输出
case通过率为92.86%
一直卡在这一步
代码如下
import java.util.*;

public class Main {

	public static void main(String[] args) {
		Scanner scan = new Scanner(System.in);
		while (scan.hasNextInt()) {
			int N = scan.nextInt();
			int K = scan.nextInt();
			int[] coins = new int[N + 1];

			for (int i = 0; i < K; i++) {
				int x = scan.nextInt();
				Set<Integer> set = new TreeSet<Integer>();
				int[] inputs = new int[2 * x];
				for (int j = 0; j < 2 * x; j++) {
					int y = scan.nextInt();
					inputs[j] = y;
					set.add(y);
				}
				String c = scan.next().trim();
				if ("=".equals(c)) {
					for (int j = 0; j < 2 * x; j++) {
						int y = inputs[j];
						coins[y] = 2;
					}
				} else {
					if ("<".equals(c)) {
						for (int j = 0; j < x; j++) {
							int y = inputs[j];
							if (coins[y] == 0) {
								coins[y] = 1;
							} else if (coins[y] == 3) {
								coins[y] = 2;
							}
						}
						for (int j = x; j < 2 * x; j++) {
							int y = inputs[j];
							if (coins[y] == 0) {
								coins[y] = 3;
							} else if (coins[y] == 1) {
								coins[y] = 2;
							}
						}
					} else {
						for (int j = 0; j < x; j++) {
							int y = inputs[j];
							if (coins[y] == 0) {
								coins[y] = 3;
							} else if (coins[y] == 1) {
								coins[y] = 2;
							}
						}
						for (int j = x; j < 2 * x; j++) {
							int y = inputs[j];
							if (coins[y] == 0) {
								coins[y] = 1;
							} else if (coins[y] == 3) {
								coins[y] = 2;
							}
						}
					}

					for (int j = 1; j <= N; j++) {
						if (!set.contains(j)) {
							coins[j] = 2;
						}
					}
				}
			}

			int falseCoin = 0;
			int count = 0;
			for (int i = 1; i <= N; i++) {
				if (coins[i] != 2) {
					falseCoin = i;
					count++;
				}
			}
			if (count == 1) {
				System.out.println(falseCoin);
			} else {
				System.out.println(0);
			}
		}

		scan.close();
	}
}


发表于 2020-03-10 17:14:23 回复(0)
#include<iostream>
#include<string>
using namespace std;
/*想找出来假币
1.找出所有正确的
2.错的很明显
=号可以找出正确的
><号可以说明等号两边有一个假币
只要<>没消去即出现在两边,那么出现次数满足要求的且只有一个的
必为所求假币
这题真的恶心,我快吐了
*/
int main()
{int N;
int K;

while(cin>>N>>K)
{bool a[1000]={};
int tmp[1001]={};
int hw[1000]={};
int lw[1000]={};
bool res[1000]={};
int time=0;//<或者>号的次数
for(int i=0;i<K;i++)
  {cin>>tmp[0];
  for(int j=0;j<2*tmp[0];j++)
    {cin>>tmp[j+1];
    }
  char x;
  cin>>x;
  if(x=='=')
  {for(int k=0;k<2*tmp[0];k++)
    {a[tmp[k+1]]=true;
     }
   }
  else if(x=='>')
  {time++;
	  for(int k=0;k<tmp[0];k++)
  {hw[tmp[k+1]]++;}
  for(int k=tmp[0];k<2*tmp[0];k++)
  {lw[tmp[k+1]]--;}}
  else
  {time++;
for(int k=0;k<tmp[0];k++)
  {lw[tmp[k+1]]--;}
  for(int k=tmp[0];k<2*tmp[0];k++)
  {hw[tmp[k+1]]++;}}
  }
int cont=0;int key=0;int cont2=0;int key2=0;
for(int i=1;i<=N;i++)
{if(a[i]==true){res[i]=true;}
else if(hw[i]==0&&lw[i]<=-time){res[i]=false;cont2++;key2=i;}
else if(hw[i]>=time&&lw[i]==0){res[i]=false;cont2++;key2=i;}

 }
for(int i=1;i<=N;i++)
{if(res[i]==false){cont++;key=i;}
}

if(cont==1){cout<<key<<endl;}
else if(cont2==1){cout<<key2<<endl;}
else{cout<<0<<endl;}
}

	return 0;
}

发表于 2020-02-13 16:53:54 回复(0)
难受,写了一上午,实际代码66行,应该算是量比较少的了,效率目前排31😀😀😀
/**
*萌新看了Faychen大佬的思路以后,只好借鉴一下,因为自己什么都不会==
*先分析解法的正确性
*大佬分析有4种状态,真币0,轻币-1,重币1,未确认2
*然后问题的答案是判断正常币的个数是不是n-1,加上状态是否非“真币”来得出
*其中关键的是硬币状态的转换
*①未确认状态:一开始大家都是未确认的状态,在称好一次之后,各个硬币都到了自己的组里
*    不可能再转换到未确认的状态;好吧,还有一直未被确认的硬币
*②轻币、重币到真币的转换:如果一个硬币既是轻币,又是重币,那么他一定是真币
*基于以上两点转换,假币最终必然没有被标记为真币,问题的解法是可行的
*/
/**
*使用一个二维数组temp[2][N/2]来记录输入的轻币和重币的编号
*其中一维下标为0表示这是轻币,一维下标为1表示这是重币
*因为轻重是后来才知道的,所以如果后面的输入是'>',还需要将两组数组中的元素交换一下
*然后根据记录轻重币编号的数组更新标记数组(根据上述所说的状态转换),出现被标记为真币的,count++
*re:实际上不能通过count计数,因为一个硬币可能被重复标记
*如此这般,完了之后
*遍历整个数组,找到假币
*/
/**
*解题调试过程:
*->编码
*->检查
*    ①判断count == n-1 写成了赋值语句
*    ②最后判断并输出结果的语句,写在了while(k--)处理输入数据的循环里
*    ③二维数组元素,res字符,在scanf中赋值又忘了写取地址符
*    ④交换二维数组元素循环次数搞错了应该是当前称重的硬币数量pi,写成了称重次数k
*    ⑤交换的语句漏写分号,int temp = temp[0][i]
*    ⑥在出现不等情况下,还需要将所有其他的未确定的硬币更新为真币,没有写这种情况
*    ⑦count未在计数前初始化为0;
*->编译
*    错误:交换数组值定义的临时变量temp和temp数组重名了,哭笑不得
*    反正编译就是会遇到错误,产生了4个error,貌似出现同名的时候,temp数组
*    被隐藏起来了,现在它只认temp这个临时变量,所以所有认为temp是数组的地方都报错了
*    共计4处error
*->自测:运行超时
*    检查循环:
*    ①有一处temp[i][j]写成了temp[i][i]
*    检查所有循环条件,貌似都有退出啊,
*    在检查输入的接收是不是不正确,比如多接受了数据,导致输入等待
*    ②发现不等情况剩余置真的代码错误
*    未发现错误,开始本地调试
*    原因是scanf接收<等字符时未将上次输入的回车吸收
*->通过自测:
*->保存并调试:
*    case通过率为71.43%
*    原因,mark[]角标范围1到n,我认为是0到n-1
*    修改:
*    ①mark初始化
*    ②剩余mark置状态为真部分
*    ③mark统计真币个数处
*/
#include "stdio.h"
#define N 1000

int main(){
    int n, k, pi, temp[2][N/2],/*题中所要求的必要的变量*/
        i, j, flag, count, mark[N]/*辅助变量*/;
    char res;
    while(scanf("%d%d", &n, &k) != EOF){
        i = n+1;
        while(--i) mark[i] = 2;//初始化所有硬币为未确定的状态
        while(k--){
            scanf("%d", &pi);
            for(i = 0; i < 2; i++){
                for(j = 0; j < pi; j++){
                    scanf("%d", &temp[i][j]);
                }
            }
            getchar();
            scanf("%c", &res);
            if(res == '='){
                for(i = 0; i < 2; i ++){
                    for(j = 0; j < pi; j++){
                        mark[temp[i][j]] = 0;
                                    //等号,则此次所称的硬币全为真币
                    }
                }
            }
            else{
                if(res == '>'){
                    i = pi;
                    while(i--){
                        int temp1 = temp[0][i];
                        temp[0][i] = temp[1][i];
                        temp[1][i] = temp1;
                    }
                }
                for(i = 0; i < 2; i++){
                    for(j = 0; j < pi; j++){
                        if(mark[temp[i][j]] == 0) continue; 
                                    //已被标记为真币,不操作
                        if(mark[temp[i][j]] == 2) mark[temp[i][j]] = 2*i - 1;
                                    //未确认的状态
                        else if(mark[temp[i][j]] != (2*i-1)) 
                                        mark[temp[i][j]] = 0;
                      //2*i-1表示的是本次被标记的类型,已有的标记值不为0和2,
                      //则本次是轻币或者重币,且上次标记和本次不同,为真币
                    }
                }
                int m = n;
                while(m){
                    flag = 1;
                    for(i = 2; i--;){
                        for(j = pi; j--;){
                            if(temp[i][j] == m) flag = 0;
                        }
                    }
                    if(flag == 1) mark[m] = 0;
                    --m;
                }
            }
        }
        i = n+1;
        count = 0;
        while(--i){
            if(!mark[i])
                count++;
            else flag = i;
        }
        if(count == n-1) printf("%d\n", flag);
        else printf("0\n");
    }
}

编辑于 2019-06-27 11:15:06 回复(0)
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <cmath>
#include <map>
#include <queue>
using namespace std;
int coin[1005];
bool flags[1005];
int main()
{
 int n,k;
 cin >> n >> k;
 for(int i = 1;i<=n;i++)
 {
 coin[i] = 0;
 flags[i] = 0;
 }
for(int i = 0 ; i<k;i++)
{
    vector<int> v1;
    vector<int> v2;
    v1.clear(); v2.clear();
    int x ; cin >> x;
    for(int j = 0 ; j<x;j++)
    {
        int y; cin >> y;
        v1.push_back(y);
    }
    for(int j = 0 ; j<x;j++)
    {
        int y; cin >> y;
        v2.push_back(y);
    }
    string s;
    cin >> s;
    if(s[0] == '=')
    {
        for(int j = 0; j<v1.size();j++)
        {
            flags[v1[j]] = -1;
        }
        for(int j = 0; j<v2.size();j++)
        {
            flags[v2[j]] = -1;
        }    
    }
    if(s[0] == '<')
    {
        falseCount++;
        for(int j = 0; j<v1.size();j++)
        {
            coin[v1[j]]--; 
        }    
        for(int j = 0; j<v2.size();j++)
        {
            coin[v2[j]]++;
        }    
    }
    if(s[0] == '>')
    {
        falseCount++;
        for(int j = 0; j<v1.size();j++)
        {
            coin[v1[j]]++;
        }    
        for(int j = 0; j<v2.size();j++)
        {
            coin[v2[j]]--; 
        }    
    }
}
int _count = 0; int ans = 0;
for(int i = 1;i<=n;i++)
{
    if(flags[i] == 0 &&  (coin[i] == falseCount || coin[i] == -falseCount))
    {
        _count++;
        ans = i;
    }
}
if(_count == 1)
cout << ans << endl;
else
cout << "0" << endl;
}
int falseCount = 0;
发表于 2019-03-04 19:11:01 回复(0)
/* 1. 将结果分为三组,相等组,小于组,大于组。
    A = B, A,B都加入相等组。
    A < B,  A加入小于组,B加入大于组,同时,不等于A或B的其他数加入相等组。
    A > B,  A加入大于组,B加入小于组,同时,不等于A或B的其他数加入相等组。
   2. 如果一个数既出现在小于组又出现在大于组,那么把它加入相等组。
   3. 判断相等组中未出现的数字,如果超过一个,则返回结果0,如果恰好为1个则结果
      为该数字。
 */

#include <stdio.h>
#include <set>

using namespace std;

int main()
{
    int n, k;
    while (scanf("%d%d", &n, &k) != EOF) {
        set<int> equal;
        set<int> less;
        set<int> great;
        while (k--) {
            int m;
            scanf("%d", &m);
            int t[2*m+1];
            for (int i = 1; i <= 2*m; ++i)
                scanf("%d", &t[i]);

            getchar();//skip 'enter'

            char flag;
            scanf("%c", &flag);

            if (flag == '<') {
                for (int i = 1; i <= m; ++i)
                    less.insert(t[i]);
                for (int i = m+1; i <= 2*m; ++i)
                    great.insert(t[i]);
                for (int i = 1; i <= n; ++i) {
                    int j;
                    for (j = 1; j <= 2*m; ++j) {
                        if (i == t[j])
                            break;
                    }
                    if (j == 2*m+1)
                        equal.insert(i);
                }
            } else if (flag == '>') {
                for (int i = 1; i <= m; ++i)
                    great.insert(t[i]);
                for (int i = m+1; i <= 2*m; ++i)
                    less.insert(t[i]);
                for (int i = 1; i <= n; ++i) {
                    int j;
                    for (j = 1; j <= 2*m; ++j) {
                        if (i == t[j])
                            break;
                    }
                    if (j == 2*m+1)
                        equal.insert(i);
                }
            } else if (flag == '=') {
                for (int i = 1; i <= 2*m; ++i)
                    equal.insert(t[i]);
            }
        }

        for (auto c : less) {
            if (great.find(c) != great.end()) {
                equal.insert(c);
            }
        }

        int cnt = 0, ans = -1;
        for (int i = 1; i <= n; ++i) {
            if (equal.find(i) == equal.end()) {
                if (++cnt > 1)
                    break;
                ans = i;
            }
        }
        if (cnt == 1)
            printf("%d\n", ans);
        else
            printf("0\n");
    }

    return 0;
}

发表于 2019-01-29 16:29:43 回复(0)

问题信息

难度:
24条回答 4381浏览

热门推荐

通过挑战的用户

查看代码