読者です 読者をやめる 読者になる 読者になる

メモ

yukicoderで遊んでいる競プロゆるふわ勢

yukicoder No.11 カードマッチ

問題はこちら
No.11 カードマッチ - yukicoder

与えられたカードたちの、スートの種類をts、数の種類をtkとすると
マッチしないものは(W-ts)*(K-tk)
なのでマッチするものはW*K-(W-ts)*(K-tk)-N

int main(){
	int s[101]={},k[101]={},w,h,n,ts,tk,i,j;
	scanf("%d%d%d",&w,&h,&n);
	for(j=0;j<n;j++){
		scanf("%d%d",&ts,&tk);
		for(i=0;s[i]!=ts&&s[i];i++);
		if(!s[i])s[i]=ts;
		//今までに登場したスートかチェック
		for(i=0;k[i]!=tk&&k[i];i++);
		if(!k[i])k[i]=tk;
		//今までに登場した数かチェック
	}
	for(ts=0;s[ts];ts++);
	for(tk=0;k[tk];tk++);
	//登場したスートと数の個数を調べる
	printf("%d",ts*h-n+(w-ts)*tk);
	//W*KがオーバーフローするのでW*K-(W-ts)*(K*tk)-Nを式変形した
	return 0;
}

いくつもループがあるのは面倒なので方針転換

s[101],k[101];
w,p,q,i,x,y,t;
main(h){
	for(scanf("%d%d%*d",&w,&h);~scanf("%d%d",&p,&q);t++){
		for(i=t;i--;){
			p*=p!=s[i];
			q*=q!=k[i];
			//既に同じ値が保存されていれば読み込んだ値を0に潰す
		}
		x+=!!p;y+=!!q;
		//0に潰されていなければ未知のものだった
		s[t]=p;k[t]=q;
		//配列への保存は、0になっていようといなかろうと行う
	}
w=!printf("%d",x*h-t+(w-x)*y);
}

2つの配列はまとめられそう

s[220],x[2];
w,p,i,t;
main(h){
	for(scanf("%d%d%*d",&w,&h);~scanf("%d",&p);x[t%2]+=!!p,s[t++]=p)for(i=t;i>1;)p*=p!=s[i-=2];
	w=!printf("%d",*x*h-t/2+(w-*x)*x[1]);
}

wとhもまとめて読みこんじゃえ

s[220];x[2];
i,t;
main(p){
	for(;~scanf("%d",&p);x[t%2]+=i>2&&p,s[t++]=p)for(i=t;i>4;)p*=p!=s[i-=2];
	i=!printf("%d",*x**s+1-t/2+(s[1]-*x)*x[1]);
//x[0]とx[1]が先ほどとは逆になったが、wとhを入れ替えてつじつまを合わせた
}

ループを圧縮すると、sのindexが1つずれて出力部が2B増えるので短縮にならなかった
140B
まだ縮みそうに見える
(iの代入とtのincが咬み合わない…)