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.
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; }
//排除法,对每个硬币进行标记,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; } }
没想到更简单的方法,求指教
#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;
}
#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; }
大家帮忙看下啊,报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;
}
}
}
}
}
#include <bits/stdc++.h>using namespace std;/*** 这题折腾了我几个小时,怀疑自己的智商了。* 解题的思路就是,有四种状态组,一种是轻的组-1,一种是重的组1,一种是正常组0,一种是未确认组2* 如果出现不等号,那么未出现在这个不等号两边的硬币一定是正常的,并且将不等号两边的分别加入各自的组* 如果一个硬币即出现在重组又出现在轻组,那么这个硬币一定是正常的* 最后看看正常的个数是不是N-1,是的话就能判断,不是就不能**/int N,K;int mark[1005];//有四种状态组,一种是轻的组-1,一种是重的组1,一种是正常组0,一种是未确认组2int tmp[1000];//记录下参与称重的硬币号int pi;//记录参与称重的硬币数bool notIn(int n){//判断当前硬币是不是参与称重了,不是返回truefor(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;}
#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; }
#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; }
/* 题目翻译: 描述: “金条”银行从可靠来源收到信息,在他们的最后一组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; }
#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")
#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; } } }
#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; }
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(); } }
#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; }
/** *萌新看了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"); } }
#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;
/* 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; }