1. 程式人生 > 其它 >原生安卓、谷歌pixel系列去除網路WiFi紅叉號

原生安卓、谷歌pixel系列去除網路WiFi紅叉號

題面

在實現程式自動分析的過程中,常常需要判定一些約束條件是否能被同時滿足。

考慮一個約束滿足問題的簡化版本:假設 \(x_1,x_2,x_3,\cdots\) 代表程式中出現的變數,給定 \(n\) 個形如 \(x_i=x_j\)\(x_i\neq x_j\) 的變數相等/不等的約束條件,請判定是否可以分別為每一個變數賦予恰當的值,使得上述所有約束條件同時被滿足。例如,一個問題中的約束條件為:\(x_1=x_2,x_2=x_3,x_3=x_4,x_4\neq x_1\),這些約束條件顯然是不可能同時被滿足的,因此這個問題應判定為不可被滿足。

現在給出一些約束滿足問題,請分別對它們進行判定。

【資料範圍】

思路

可以用並查集維護。

如果相等,那麼合併。如果不等,檢查是否在一個集合中,如果在就是 NO, 否則就是 YES

至於值域問題,可以考慮以下方案:

  • 離散化
  • 使用對映資料結構(如 std::mapstd::unordered_map__gnu_pbds::gp_hash_table 等)。

這裡使用第二種。經過實驗,只有 std::unordered_map 能過。其他都是 \(90\) 分(開了 \(\text{O2}\) )。

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

const int SIZE = 1e6+5;
int t,T;
struct query{
	int i,j,e;
} querys[SIZE];

unordered_map<int,int> fa;

namespace IO{
	const int SIZE=1<<21;
	static char ibuf[SIZE],obuf[SIZE],*iS,*iT,*oS=obuf,*oT=oS+SIZE-1;
    int qr;
    char qu[55],c;
    bool f;
	#define getchar() (IO::iS==IO::iT?(IO::iT=(IO::iS=IO::ibuf)+fread(IO::ibuf,1,IO::SIZE,stdin),(IO::iS==IO::iT?EOF:*IO::iS++)):*IO::iS++)
	#define putchar(x) *IO::oS++=x,IO::oS==IO::oT?flush():0
	#define flush() fwrite(IO::obuf,1,IO::oS-IO::obuf,stdout),IO::oS=IO::obuf
	#define puts(x) IO::Puts(x)
	template<typename T>
    inline void read(T&x){
    	for(f=1,c=getchar();c<48||c>57;c=getchar())f^=c=='-';
    	for(x=0;c<=57&&c>=48;c=getchar()) x=(x<<1)+(x<<3)+(c&15); 
    	x=f?x:-x;
    }
    template<typename T>
    inline void write(T x){
        if(!x) putchar(48); if(x<0) putchar('-'),x=-x;
        while(x) qu[++qr]=x%10^48,x/=10;
        while(qr) putchar(qu[qr--]);
    }
    inline void Puts(const char*s){
    	for(int i=0;s[i];i++)
			putchar(s[i]);
		putchar('\n');
	}
	struct Flusher_{~Flusher_(){flush();}}io_flusher_;
}
using IO::read;
using IO::write;
int find(int x){
	if(fa[x]==x)return x;
	else return fa[x]=find(fa[x]);
}

void merge(int x,int y){
	fa[find(x)]=find(y);
}

bool same(int x,int y){
	return find(x)==find(y);
}

void solve(){
	read(t);
	for(int i=1;i<=t;i++){
		query &nq=querys[i];
		read(nq.i);read(nq.j);read(nq.e);
	}
	for(int i=1;i<=t;i++){
		query &nq=querys[i];
		fa[nq.i]=nq.i;
		fa[nq.j]=nq.j;
	}
	for(int i=1;i<=t;i++){
		query &nq=querys[i];
		if(nq.e==1){
			merge(nq.i,nq.j);
		}
	}
	for(int i=1;i<=t;i++){
		query &nq=querys[i];
		if(nq.e==0){
			if(same(nq.i,nq.j)){
				putchar('N');putchar('O');putchar('\n');
				return;
			}
		}
	}
	putchar('Y');putchar('E');putchar('S');putchar('\n');
}

int main(){
   read(T);
	while(T--){
		solve();
	}
	return 0;
}

建議使用 C++14 (GCC 9) O2

AC 記錄