A. Rudolph and Cut the Rope
题意:n个钉子的高度为hi , 绑着糖果绳子长度为li,问要切断几根绳子能让糖果到达底面,很明显应该将高度大于绳子长度的即可
AC代码
void solved()
{
int n;
cin >> n;
int ans = 0;
while(n -- )
{
int a , b;
cin >> a >> b;
if(a > b) ans ++;
}
cout << ans << endl;
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int t = 1;
cin >> t;
while(t -- )
solved();
return 0;
}
B. Rudolph and Tic-Tac-Toe
题解:明显井字棋只有8种赢法,三行,三列,两对角线,所以只要枚举这八种即可
AC代码
void solved()
{
vector<string> a(3);
for(int i = 0 ; i < 3 ; i ++ ) cin >> a[i];
for(int i = 0 ; i < 3 ; i ++ )
{
if(a[i][0] == a[i][1] && a[i][0] == a[i][2] && a[i][0] != '.')
{
cout << a[i][0] << endl;
return ;
}
if(a[0][i] == a[1][i] && a[1][i] == a[2][i] && a[0][i] != '.')
{
cout << a[0][i] << endl;
return ;
}
}
if(a[0][0] == a[1][1] && a[0][0] == a[2][2] && a[0][0] != '.')
{
cout << a[0][0] << endl;
return ;
}
if(a[0][2] == a[1][1] && a[1][1] == a[2][0] && a[0][2] != '.')
{
cout << a[1][1] << endl;
return ;
}
cout << "DRAW\n";
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int t = 1;
cin >> t;
while(t -- )
solved();
return 0;
}
C. Rudolf and the Another Competition
题解:很明显,要想罚时最小且过最多的题目,肯定从耗时少的题目开始,只要注意排序规则就行
AC代码
bool cmp(array<LL , 3> &a , array<LL , 3> &b)
{
if(a[0] != b[0]) return a[0] > b[0];
if(a[1] != b[1]) return a[1] < b[1];
return a[2] < b[2];
}
void solved()
{
int n , m , h;
cin >> n >> m >> h;
vector<array<LL , 3>> ans(n);
vector<LL> a(m + 1);
for(int i = 0 ; i < n ; i ++ )
{
for(int j = 1 ; j <= m ; j ++ ) cin >> a[j];
sort(a.begin() + 1 , a.end());
LL sum = 0;
for(int j = 1 ; j <= m ; j ++ ) a[j] += a[j - 1];
int j = 0;
for(j = 0 ; j < m ; j ++ )
if(a[j + 1] <= h) sum += a[j + 1];
else break;
ans.push_back({j , sum , i});
}
sort(ans.begin() , ans.end() , cmp);
/*for(int i = 0 ; i < n ; i ++ )
cout << ans[i][0] << " " << ans[i][1] << " " << ans[i][2] << endl;*/
for(int i = 0 ; i < n ; i ++ )
if(ans[i][2] == 0)
{
cout << i + 1 << endl;
break;
}
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int t = 1;
cin >> t;
while(t -- )
solved();
return 0;
}
D. Rudolph and Christmas Tree
题解:明显如果两棵树的距离大于等于高度,那么就没有重合,如果小于,那么就得减去重合的三角形,那么重合的三角形高为h - (a[i + 1] - a[i - 1]) , 由相似三角形得,该面积为(高 / h)^ 2 * 原三角形的面积
AC代码
void solved()
{
long double n , d , h;
cin >> n >> d >> h;
long double ans = 0;
vector<long double> a(n);
for(int i = 0 ; i < n ; i ++ ) cin >> a[i];
int last = -1;
for(int i = 0 ; i < n ; i ++ )
{
if(last == -1)
{
ans += d * h / 2;
last = a[i];
}else
{
if(a[i] >= last + h) ans += d * h / 2;
else
{
long double s = h - a[i] + last;
ans += d * h / 2 - s / h * s / h * d * h / 2;
}
last = a[i];
}
}
printf("%.8Lf\n" , ans);
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int t = 1;
cin >> t;
while(t -- )
solved();
return 0;
}
E2. Rudolf and Snowflakes (hard version)
题解:题意可知,需开两次以上的花才行,即为k进制且每位都为1而且长度大于2,所以可以枚举 i 长度为3 ~ 64(因为2^64 > 1e18),用等比数列求和公式,n == (k ^ i - 1) / (k - 1) ,所以该等式是随k增大而增大,所以可以二分k,由于hard会爆LL,所以需特殊处理
AC代码
LL n;
bool check(LL len , LL x)
{
LL sum = 0;
LL t = 1;
for(int i = 0 ; i < len ; i ++ )
{
sum += t;
if(sum > n) return false;
if(t > n / x && i != len - 1) return false;
t = t * x;
}
return true;
}
void solved()
{
cin >> n;
for(LL i = 3 ; i <= 64 ; i ++ )
{
LL l = 2 , r = 1e10;
while(l < r)
{
LL mid = l + r + 1 >> 1;
if(check(i , mid)) l = mid;
else r = mid - 1;
}
LL sum = 0;
LL t = 1;
for(int j = 0 ; j < i ; j ++ )
{
sum += t;
t = t * l;
}
if(sum == n && n >= 7)
{
cout << "Yes\n";
return ;
}
}
cout << "No\n";
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int t = 1;
cin >> t;
while(t -- )
solved();
return 0;
}