トピックリンク
回答
題名
配列の最後に既存の番号を追加するか、配列の番号に1
演算を追加して配列値を等しくn
することにより、最小のオペランドを見つけます。
アイデア
いくつかの例を書いてください。そうすれば、途中で操作ステップの数が最小になることがわかります。
(実際には、小学校で既知の長方形領域の最小辺の長さを見つけることと同じです。
たとえば、
42
1 42 : 41
2 21 : 40
........
ACコード
初版
最後の数分で、私はその方法を考えて、それをシミュレートしましたが、それは1秒遅れました。。。。
#include <bits/stdc++.h>
using namespace std;
//#pragma GCC optimize(2)
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define ull unsigned long long
#define ll long long
#define rep(i, x, y) for(int i=x;i<=y;i++)
#define mms(x, n) memset(x, n, sizeof(x))
#define mmc(A, tree) memcpy(A, tree, sizeof(tree))
#define eps (1e-8)
#define PI (acos(-1.0))
#define INF (0x3f3f3f3f)
#define mod (ll)(1e9+7)
typedef pair<int, int> P;
int main() {
#ifndef ONLINE_JUDGE
freopen("input.txt", "r", stdin);
#endif
int T;cin >> T;
while (T--) {
int n;cin >> n;
int ans = INF;
for (int t = floor(sqrt(n) + 1); t >= 1; t--) {
if (t * ceil((double(n) / t)) >= n) {
ans = min(ans, (int)(t + ceil(double(n) / t) - 2));
}
}
cout << ans << endl;
}
return 0;
}
第2版
これを考えた後、シミュレーションは必要ありません。中間の値を取るだけです。
#include <bits/stdc++.h>
using namespace std;
//#pragma GCC optimize(2)
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define ull unsigned long long
#define ll long long
#define rep(i, x, y) for(int i=x;i<=y;i++)
#define mms(x, n) memset(x, n, sizeof(x))
#define mmc(A, tree) memcpy(A, tree, sizeof(tree))
#define eps (1e-8)
#define PI (acos(-1.0))
#define INF (0x3f3f3f3f)
#define mod (ll)(1e9+7)
typedef pair<int, int> P;
int main() {
#ifndef ONLINE_JUDGE
freopen("input.txt", "r", stdin);
#endif
int T;
cin >> T;
while (T--) {
int n;cin >> n;
int t = int(floor(sqrt(n)));
int ans = t + int(ceil(double(n) / t));
cout << ans - 2 << endl;
}
return 0;
}
ボスコード
ええと、上司はとても短いです。
(私が書いたことに注意してください
#include<bits/stdc++.h>
int N;
int main() {
for (std::cin >> N; std::cin >> N; std::cout << ceil(2 * sqrt(N)) - 2 << ' ');
// 如果先ceil后*2会导致所得的结果较小。
// 不好理解的话可以画一个正方形,然后求他的最小周长。
}