Codeforces Round 883 (Div. 3)

题目链接

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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值