SRM 517 250pt: CompositeSmash

問題概要

整数N(<10^5)が与えられる。整数は二つの整数の積に再帰的に分解される。途中でtargetという値が必ず現れるかどうか判定する問題。

考えたこと

  • Nが大したことないし普通に愚直に探索で間に合いそう。
  • 書けた。メモ化も付けることができるけど、最大ケースだと思われるのが余裕で間に合ってるし、今日のセットはmediumが600で250早解きになる可能性が高いのでさっさと出す。
  • 一応いろんなケース試して余裕で間に合っていたので再提出はしなかった。無事AC。
  • 最近強く意識している、「基本は全探索」、「間に合うなら最もシンプルに書くべし」というのが生きた問題だった。easyが早解きできるようになるとレートは安定する。

本番で通ったコード

計算量よく分かんない。最大ケースは(65536, 2)だと思われる。

#include <string>
#include <vector>
using namespace std;

struct CompositeSmash {

	string thePossible(int N, int target) {
		return solve(N, target) ? "Yes": "No";
	}

	bool solve(int N, int target){
		if(N==target){
			return true;
		}

		vector<int> fs;
		for(int i=2; i*i<=N; i++){
			if(N%i == 0){
				fs.push_back(i);
			}
		}

		if(fs.empty()){
			return false;
		}

		for(int i=0; i<(int)fs.size(); i++){
			if( !(solve(N/fs[i], target) || solve(fs[i], target) ) ){
				return false;
			}
		}

		return true;
	}

};