Codeforces Beta Round #95 (Div. 2) A : cAPS lOCK

問題概要

文字列が与えられる。全てが大文字、または先頭以外の全てが大文字なら大文字と小文字を入れ替えて出力する。

解法

愚直にチェックしても間に合う。1文字目は無視してよいことに気づけばちょっとだけコーディング量が減る。入力が1文字で小文字のときは変換しないと思っていたけどするらしい。よく分からない。isupperの返り値は0 or 1ではないので、bool型変数に&=するのは危険。

本番で通ったコード

計算量O(strlen)。

#include <cstdio>
#include <cstring>
#include <cctype>
using namespace std;

const int MAX_L = 100;

char str[MAX_L + 1];

void solve(){
	const int L = strlen(str);
	bool change = false;

	//check 1
	bool allupper = true;
	for(int i=1; i<L; i++){
		if(!isupper(str[i])){
			allupper = false;
		}
	}
	if(allupper){
		change = true;
	}

	if(change){
		for(int i=0; i<L; i++){
			if(isupper(str[i])){
				str[i] = tolower(str[i]);
			}
			else{
				str[i] = toupper(str[i]);
			}
		}
	}

}

int main(){

	scanf("%[^\n]%*c", str);
	solve();
	puts(str);

	return 0;
}

大文字、小文字の変換はstr[i] ^= 32;でできるらしい。