結果

問題 No.4 おもりと天秤
ユーザー plasma_eplasma_e
提出日時 2017-02-06 20:49:58
言語 C++14
(gcc 13.2.0 + boost 1.83.0)
結果
AC  
実行時間 203 ms / 5,000 ms
コード長 13,908 bytes
コンパイル時間 1,132 ms
コンパイル使用メモリ 114,176 KB
実行使用メモリ 13,796 KB
最終ジャッジ日時 2023-09-08 17:19:00
合計ジャッジ時間 3,370 ms
ジャッジサーバーID
(参考情報)
judge12 / judge13
このコードへのチャレンジ(β)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 2 ms
4,376 KB
testcase_01 AC 2 ms
4,376 KB
testcase_02 AC 2 ms
4,376 KB
testcase_03 AC 2 ms
4,380 KB
testcase_04 AC 4 ms
4,376 KB
testcase_05 AC 174 ms
12,732 KB
testcase_06 AC 1 ms
4,380 KB
testcase_07 AC 187 ms
13,140 KB
testcase_08 AC 4 ms
4,380 KB
testcase_09 AC 4 ms
4,380 KB
testcase_10 AC 203 ms
13,796 KB
testcase_11 AC 1 ms
4,380 KB
testcase_12 AC 1 ms
4,376 KB
testcase_13 AC 2 ms
4,376 KB
testcase_14 AC 2 ms
4,376 KB
testcase_15 AC 2 ms
4,376 KB
testcase_16 AC 2 ms
4,376 KB
testcase_17 AC 2 ms
4,380 KB
testcase_18 AC 78 ms
8,184 KB
testcase_19 AC 164 ms
12,000 KB
testcase_20 AC 158 ms
11,916 KB
testcase_21 AC 143 ms
11,492 KB
testcase_22 AC 152 ms
11,596 KB
権限があれば一括ダウンロードができます
コンパイルメッセージ
main.cpp:78:101: 警告: friend declaration ‘constexpr decltype(auto) utility::operator+(const addable<T>&, const addable<T>&)’ declares a non-template function [-Wnon-template-friend]
   78 |                 friend constexpr decltype(auto) operator+(addable<T>const& lhs, addable<T>const& rhs);
      |                                                                                                     ^
main.cpp:78:101: 備考: (if this is not what you intended, make sure the function template has already been declared and add ‘<>’ after the function name here)
main.cpp:87:111: 警告: friend declaration ‘constexpr decltype(auto) utility::operator-(const subtractable<T>&, const subtractable<T>&)’ declares a non-template function [-Wnon-template-friend]
   87 |                 friend constexpr decltype(auto) operator-(subtractable<T>const& lhs, subtractable<T>const& rhs);
      |                                                                                                               ^
main.cpp:95:111: 警告: friend declaration ‘constexpr decltype(auto) utility::operator*(const multipliable<T>&, const multipliable<T>&)’ declares a non-template function [-Wnon-template-friend]
   95 |                 friend constexpr decltype(auto) operator*(multipliable<T>const& lhs, multipliable<T>const& rhs);
      |                                                                                                               ^
main.cpp:103:105: 警告: friend declaration ‘constexpr decltype(auto) utility::operator/(const dividable<T>&, const dividable<T>&)’ declares a non-template function [-Wnon-template-friend]
  103 |                 friend constexpr decltype(auto) operator/(dividable<T>const& lhs, dividable<T>const& rhs);
      |                                                                                                         ^

ソースコード

diff #

#include<iostream>
#include<vector>
#include<set>
#include<algorithm>
#include<queue>
#include<functional>
#include<numeric>
#include<limits>
#include<map>
#include<bitset>
#include<array>
#include<random>

namespace utility
{
	template<class T>struct addable;
	template<class T>struct subtractable;
	template<class T>struct multipliable;
	template<class T>struct dividable;
	template<class T,class U>constexpr decltype(auto) operator+(T const& lhs, U const& rhs)
	{
		auto x = lhs;
		x += rhs;
		return x;
	}
	template<class T, class U>constexpr decltype(auto) operator-(T const& lhs, U const& rhs)
	{
		auto x = lhs;
		x -= rhs;
		return x;
	}
	template<class T, class U>constexpr decltype(auto) operator*(T const& lhs, U const& rhs)
	{
		auto x = lhs;
		x *= rhs;
		return x;
	}
	template<class T, class U>constexpr decltype(auto) operator/(T const& lhs, U const& rhs)
	{
		auto x = lhs;
		x /= rhs;
		return x;
	}
	template<class T>struct equality_comparable
	{
		constexpr decltype(auto) operator!=(equality_comparable<T>const& rhs)const
		{
			return !(static_cast<T const&>(*this) == static_cast<T const&>(rhs));
		}

	};
	template<class T>struct less_than_comparable
	{
		constexpr decltype(auto)operator<(equality_comparable<T>const& rhs)const
		{
			return static_cast<T const&>(*this) < static_cast<T const&>(rhs);
		}
		constexpr decltype(auto)operator>(T const& rhs)const
		{
			return rhs < *this;
		}
		constexpr decltype(auto)operator<=(T const& rhs)const
		{
			return !(rhs < *this);
		}
		constexpr decltype(auto)operator>=(T const& rhs)const
		{
			return !(*this < rhs);
		}

	};
	template<class T>struct addable
	{
		constexpr decltype(auto) operator+=(addable<T>const& rhs)
		{
			return static_cast<T const&>(*this) += static_cast<T const&>(rhs);
		}
		friend constexpr decltype(auto) operator+(addable<T>const& lhs, addable<T>const& rhs);
	};
	template<class T>struct subtractable
	{
		constexpr decltype(auto) operator-=(subtractable<T>const& rhs)
		{
			return static_cast<T const&>(*this) -= static_cast<T const&>(rhs);
		}

		friend constexpr decltype(auto) operator-(subtractable<T>const& lhs, subtractable<T>const& rhs);
	};
	template<class T>struct multipliable
	{
		constexpr decltype(auto) operator*=(multipliable<T>const& rhs)
		{
			return static_cast<T const&>(*this) *= static_cast<T const&>(rhs);
		}
		friend constexpr decltype(auto) operator*(multipliable<T>const& lhs, multipliable<T>const& rhs);
	};
	template<class T>struct dividable
	{
		constexpr decltype(auto) operator/=(dividable<T>const& rhs)
		{
			return static_cast<T const&>(*this) /= static_cast<T const&>(rhs);
		}
		friend constexpr decltype(auto) operator/(dividable<T>const& lhs, dividable<T>const& rhs);
	};

	struct nullopt_t
	{

	};
	constexpr nullopt_t nullopt{};
	template<class T>class optional:private equality_comparable<optional<T>>
	{
		union
		{
			T val;
			nullopt_t null;
		};
		bool flag;
	public:
		constexpr optional(nullopt_t n = nullopt) : null(), flag(false)
		{

		}

		constexpr T& operator*()
		{
			if (flag)
			{
				return val;
			}
			throw std::invalid_argument("this optional value has not any value");
		}
		constexpr T const& operator*()const
		{
			if (flag)
			{
				return val;
			}
			throw std::invalid_argument("this optional value has not any value");
		}
		constexpr void reset()
		{
			null = nullopt;
			flag = false;
		}
		constexpr operator bool()const
		{
			return flag;
		}
		template<class... Us>void emplace(Us&&... args)
		{
			val = T(std::forward<Us>(args)...);
			flag = true;
		}
		constexpr auto& operator=(T const& v)
		{
			val = v;
			flag = true;
			return *this;
		}
		constexpr auto& operator=(T&& v)
		{
			val = v;
			flag = true;
			return *this;
		}
		constexpr auto& operator=(nullopt_t)
		{
			null = nullopt;
			flag = false;
			return *this;
		}

		constexpr optional(T const& v) :optional()
		{
			*this = v;
		}
		constexpr optional(T&& v) : optional()
		{
			*this = std::move(v);
		}

		constexpr bool operator==(optional const& rhs)const
		{
			return flag&&rhs.flag ? val == rhs.val : flag == rhs.flag;
		}

		optional(optional const&) = default;
		optional(optional&&) = default;
		optional& operator=(optional const&) = default;
		optional& operator=(optional&&) = default;
		~optional() = default;
		
	};
}
namespace math
{
	template<class T>constexpr T pow(T val, std::uint64_t p)
	{
		return p == 0 ? T(1) :
			p == 1 ? val :
			p == 2 ? val*val :
			p % 2 == 0 ? pow(pow(val, p / 2), 2) :
			pow(pow(val, p / 2), 2)*val;
	}
	template<class T,class U>constexpr int ilog(T val, U base)
	{
		T v(1);
		for (int i{};;++i)
		{
			if (val <= v)
			{
				return i;
			}
			v *= base;
		}
	}

	template<std::uint64_t Mod>class mod_number:
		private utility::equality_comparable<mod_number<Mod>>,
		private utility::addable<mod_number<Mod>>,
		private utility::subtractable<mod_number<Mod>>,
		private utility::multipliable<mod_number<Mod>>,
		private utility::dividable<mod_number<Mod>>
	{
		std::uint64_t value;
	public:
		mod_number(std::uint64_t v = 0) :value(v%Mod)
		{

		}
		mod_number(int v) :value(v%Mod)
		{

		}
		mod_number(std::int64_t v) :value(v%Mod)
		{

		}
		mod_number(std::uint32_t v) :value(v%Mod)
		{

		}

		bool operator==(mod_number const& rhs)
		{
			return value == rhs.value;
		}

		auto& operator+=(mod_number const& rhs)
		{
			value += rhs.value;
			value %= Mod;
			return *this;
		}

		auto& operator-=(mod_number const& rhs)
		{
			value += Mod - rhs.value;
			value %= Mod;
			return *this;
		}

		auto& operator*=(mod_number const& rhs)
		{
			value *= rhs.value;
			value %= Mod;
			return *this;
		}

		auto& operator/=(mod_number const& rhs)
		{
			return operator*=(pow(rhs, Mod - 2));
		}
	};
	constexpr int bitcount(unsigned int x)
	{
		x = (x & 0x55555555) + ((x & 0xAAAAAAAA) >> 1);
		x = (x & 0x33333333) + ((x & 0xCCCCCCCC) >> 2);
		x = (x & 0x0F0F0F0F) + ((x & 0xF0F0F0F0) >> 4);
		x = (x & 0x00FF00FF) + ((x & 0xFF00FF00) >> 8);
		x = (x & 0x0000FFFF) + ((x & 0xFFFF0000) >> 16);
		return static_cast<int>(x);
	}
	constexpr int bitcount(unsigned long long x)
	{
		x = (x & 0b0101010101010101010101010101010101010101010101010101010101010101) + ((x & 0b1010101010101010101010101010101010101010101010101010101010101010) >> 1);
		x = (x & 0b0011001100110011001100110011001100110011001100110011001100110011) + ((x & 0b1100110011001100110011001100110011001100110011001100110011001100) >> 2);
		x = (x & 0b0000111100001111000011110000111100001111000011110000111100001111) + ((x & 0b1111000011110000111100001111000011110000111100001111000011110000) >> 4);
		x = (x & 0b0000000011111111000000001111111100000000111111110000000011111111) + ((x & 0b1111111100000000111111110000000011111111000000001111111100000000) >> 8);
		x = (x & 0b0000000000000000111111111111111100000000000000001111111111111111) + ((x & 0b1111111111111111000000000000000011111111111111110000000000000000) >> 16);
		x = (x & 0b0000000000000000000000000000000011111111111111111111111111111111) + ((x & 0b1111111111111111111111111111111100000000000000000000000000000000) >> 32);
		return static_cast<int>(x);
	}
	constexpr int bitcount(int x)
	{
		return bitcount(static_cast<unsigned int>(x));
	}
	constexpr int bitcount(long long x)
	{
		return bitcount(static_cast<unsigned long long>(x));
	}

	constexpr auto infinity = utility::nullopt;
	template<class T>class infable :
		private utility::addable<T>,
		private utility::subtractable<T>,
		private utility::multipliable<T>,
		private utility::dividable<T>,
		private utility::equality_comparable<T>,
		private utility::less_than_comparable<T>
	{
		utility::optional<T> val;
	public:
		constexpr infable(T v = T()) :val(v)
		{
			
		}
		constexpr infable(utility::nullopt_t) : val()
		{

		}

		constexpr T const& get()const
		{
			return *val;
		}

		constexpr bool operator<(infable<T>const& rhs)const
		{
			if (val&&rhs.val)
			{
				return *val < rhs.get();
			}
			else if (val && !rhs.val)
			{
				return true;
			}
			else
			{
				return false;
			}
		}

		constexpr bool operator==(infable<T>const& rhs)const
		{
			return val == rhs.val;
		}

		constexpr decltype(auto) operator+=(infable<T>const& rhs)
		{
			if (val)
			{
				if (rhs.val)
				{
					*val += rhs.get();
				}
				else
				{
					val = infinity;
				}
			}
			return *this;
		}
		constexpr decltype(auto) operator-=(infable<T>const& rhs)
		{
			if (val)
			{
				if (rhs.val)
				{
					*val -= rhs.get();
				}
				else
				{
					val = infinity;
				}
			}
			return *this;
		}
		constexpr decltype(auto) operator*=(infable<T>const& rhs)
		{
			if (val)
			{
				if (rhs.val)
				{
					*val *= rhs.get();
				}
				else
				{
					val = infinity;
				}
			}
			return *this;
		}
		constexpr decltype(auto) operator/=(infable<T>const& rhs)
		{
			if (val)
			{
				if (rhs.val)
				{
					*val /= rhs.get();
				}
				else
				{
					val = infinity;
				}
			}
			return *this;
		}

	};
}
namespace container
{
	namespace detail
	{
		template<class T, std::size_t Depth>struct tree_array
		{
			std::array<T, (1 << (Depth + 1)) - 1> ar;
			constexpr T& operator()(std::size_t index, std::size_t depth)
			{
				return ar[(1ull << depth) + index - 1];
			}
			constexpr T const& operator()(std::size_t index, std::size_t depth)const
			{
				return ar[(1ull << depth) + index - 1];
			}
		};
	}

	template<class T, std::size_t Size = 1 << 13>class addtree
	{
		std::array<T, 2 * Size - 1> data;
		T get(std::size_t left, std::size_t right, std::size_t i, std::size_t l, std::size_t r)
		{
			if (r <= left || right <= l)
				return T();
			if (left <= l&&r <= right)
			{
				return data[i];
			}
			else
			{
				return 
					get(left, right, 2 * i + 1, l, (l + r) / 2) +
					get(left, right, 2 * i + 2, (l + r) / 2, r);
			}
		}
	public:
		addtree() :data{}
		{

		}
		void change(T const& val, std::size_t index)
		{
			T from = data[index + Size - 1];
			for (std::size_t i = 1, c = math::ilog(Size, 2);i <= Size;(i <<= 1), --c)
			{
				data[i + (index >> c) - 1] -= from;
				data[i + (index >> c) - 1] += val;
			}
		}
		auto begin()const
		{
			return std::next(data.begin(), Size - 1);
		}
		auto end()const
		{
			return data.end();
		}
		T get(std::size_t left, std::size_t right)
		{
			return left > right ? T() : get(left, right + 1, 0, 0, Size);
		}
	};
	template<class T, std::size_t Depth = 13>class minmaxtree
	{
		detail::tree_array<std::pair<T, T>, Depth> data;
		T min(std::size_t left, std::size_t right, std::size_t L, std::size_t R, std::size_t depth)const
		{
			if (right <= L || R <= left)
			{
				return std::numeric_limits<T>::max();
			}
			else if (left <= L&&R <= right)
			{
				return data(L >> (Depth - depth), depth).first;
			}
			else
			{
				return std::min(
					min(left, right, L, (L + R) / 2, depth + 1),
					min(left, right, (L + R) / 2, R, depth + 1));
			}
		}
		T max(std::size_t left, std::size_t right, std::size_t L, std::size_t R, std::size_t depth)const
		{
			if (right <= L || R <= left)
			{
				return std::numeric_limits<T>::min();
			}
			else if (left <= L&&R <= right)
			{
				return data(L >> (Depth - depth), depth).second;
			}
			else
			{
				return std::max(
					max(left, right, L, (L + R) / 2, depth + 1),
					max(left, right, (L + R) / 2, R, depth + 1));
			}
		}
	public:
		void change(T const& val, std::size_t index)
		{
			data(index, Depth).first = val;
			data(index, Depth).second = val;
			for (int i = 1;i <= Depth;++i)
			{
				data(index >> i, Depth - i).first = std::min(
					data((index >> i) << 1, Depth - i + 1).first,
					data(((index >> i) << 1) + 1, Depth - i + 1).first);
				data(index >> i, Depth - i).second = std::max(
					data((index >> i) << 1, Depth - i + 1).second,
					data(((index >> i) << 1) + 1, Depth - i + 1).second);
			}
		}
		T min(std::size_t left, std::size_t right)const
		{
			return right < left ? std::numeric_limits<T>::max() : min(left, right + 1, 0, 1 << Depth, 0);
		}
		T max(std::size_t left, std::size_t right)const
		{
			return right < left ? std::numeric_limits<T>::min() : max(left, right + 1, 0, 1 << Depth, 0);
		}

		minmaxtree() :data{}
		{

		}

	};

	template<class T>using dijkstra_queue = std::priority_queue<T, std::vector<T>, std::greater<>>;
}
namespace algorithm
{
	template<class RandomAccessRange>void sort(RandomAccessRange& range)
	{
		std::sort(std::begin(range), std::end(range));
	}
	template<class T, std::size_t I>void sort(T(&range)[I])
	{
		std::sort(std::begin(range), std::end(range));
	}
}

void Main();
int main()
{
	std::ios::sync_with_stdio(false);
	Main();
}
//撣

int check(std::size_t i, std::size_t j, std::vector<int>const& vec, int N)
{
	static std::map<int, std::map<int, int>> memo;
	if (memo.count(i))
	{
		if (memo[i].count(j))
		{
			return memo[i][j];
		}
	}
	if (i == N)
	{
		memo[i][j] = 0;
	}
	else if (vec[i] > j)
	{
		memo[i][j] = check(i + 1, j, vec, N);
	}
	else
	{
		memo[i][j] = check(i + 1, j, vec, N);
		memo[i][j] = std::max(memo[i][j], check(i + 1, j - vec[i], vec, N) + vec[i]);
	}
	return memo[i][j];
}
void Main()
{
	int N;
	std::cin >> N;
	std::vector<int> vec(N);
	int sum{};
	for (auto& v : vec)
	{
		std::cin >> v;
		sum += v;
	}
	if (2 * check(0, sum / 2, vec, N) == sum)
	{
		std::cout << "possible" << std::endl;
	}
	else
	{
		std::cout << "impossible" << std::endl;
	}
}
0