CF之旅

本文提供了几道算法题目的解答过程及思路,包括利用二分查找优化照明问题、字符串处理算法、通过贪心策略解决路灯覆盖问题等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意: 

一条长度为L的街道,上有N个灯,给出N个灯所在的位置(0<=ai<=L)。问灯的最小半径为多少才能照亮整个街道。 

题目说是用二分,然后用二分做了...在第九个案例给跪了。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
typedef long long ll;
double a[10005];
int n;
ll m;
bool BS(double mid)
{
	bool temp = false;
	double num = 0;
	int i = 0;
	if(n == 1)
    {
       if(a[0] == 0)
        {
            if(a[0] + mid >= m)
                return true;
            else
                return false;
        }
        if(a[0] != 0)
        {
            if(num + mid >= a[0] && a[0] + mid >= m)
                return true;
            else
                return false;
        }
    }
	for(i = 0 ; i < n ; i ++ )
	{


		if(i == 0 && a[i] != 0)
		{
			if(num + mid >= a[i])
			{
				num = a[i];
				temp = true;
				continue;
			}
			else
			{
				return false;
			}
		}
		if(num + mid >= a[i] - mid )
		{
			num  = a[i];
			temp = true;
		}
		else
		{
			return false;
		}
	}
	if(num + mid >= m)
		return true;
}
int main()
{
	cin >> n >> m;
	for(int i = 0; i < n;i++)
	{
		cin >> a[i];
	}
	sort(a,a+n);
	double left = 0 ;
	double right = m+1;
	for(int i = 0; i < 100; i ++)
	{
		double mid = (left + right) / 2;
		if(BS(mid))
			right = mid;
		else
			left = mid;
	}
	printf("%.10f\n",right);
}

然后看了别人的做法AC了,用贪心只需要比较前后和相邻的最大值就ok,自己太水了。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
typedef long long ll;
double a[1005];
int main()
{
	int n;
	double m;
	cin >> n >> m;
	for(int i = 0 ; i < n ; i ++)
		cin >> a[i];
	sort(a,a+n);
	double Max = max (a[0] - 0,m - a[n -1]);
	for(int i = 1; i < n;i++)
	{
		Max = max((a[i]- a[i-1])/2,Max);
	}
	printf("%.10lf\n",Max);
}

题意是给一个long long 的数让你交换k次 让这个数最大

#include <iostream>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;1
int main()
{
    char a[20];
    int k;
    cin >> a >> k;
    if(k == 0 || strlen(a) == 1)
        cout << a << endl;
    else
    {
        int A[20];
        for(int i = 0 ; i < strlen(a);i++)
        {
            A[i] = a[i] - 48;
        }
        for(int i = 0; i < strlen(a) && k ;i++)
        {
            int ans = i;
            for(int j = i + 1;j < strlen(a) && j - i <= k;j++)
            {
                if(A[j] > A[ans]) //一定是大于A[ans],找出最大的下标不是比i大的。
                {
                    ans = j;
                }
            }
            k -= (ans - i);
            for(int w = ans; w > i ;w --)
            {
                int t = A[w];
                A[w] = A[w-1];
                A[w-1] = t;
            }
        }
        for(int i = 0; i < strlen(a);i++)
            cout << A[i] ;
        cout << endl;
    }
}

B. Pasha and String
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Pasha got a very beautiful string s for his birthday, the string consists of lowercase Latin letters. The letters in the string are numbered from 1 to |s| from left to right, where |s| is the length of the given string.

Pasha didn’t like his present very much so he decided to change it. After his birthday Pasha spent m days performing the following transformations on his string — each day he chose integer ai and reversed a piece of string (a segment) from position ai to position |s| - ai + 1. It is guaranteed that ai ≤ |s|.

You face the following task: determine what Pasha’s string will look like after m days.

Input

The first line of the input contains Pasha’s string s of length from 2 to 2·105 characters, consisting of lowercase Latin letters.

The second line contains a single integer m (1 ≤ m ≤ 105) —  the number of days when Pasha changed his string.

The third line contains m space-separated elements ai (1 ≤ aiai ≤ |s|) — the position from which Pasha started transforming the string on the i-th day.

Output

In the first line of the output print what Pasha’s string s will look like after m days.

Examples
Input
abcdef
1
2
Output
aedcbf
Input
vwxyz
2
2 2
Output
vwxyz
Input
abcdef
3
1 2 3
Output
fbdcea
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define N 200000+100
char str[N];
int vis[N];

int main()
{
    int n, x;
    scanf("%s",str);
    scanf("%d",&n);
    for(int i = 0;i < n; i++) {
        scanf("%d",&x);
        vis[x]++;
    }
    int len = (int)strlen(str);
    int sum = 0;
    for(int i = 0;i < len/2; i++)//由于是二分,标记后都是1,实现某点到中间翻转。     {
        sum += vis[i+1];
        if(sum&1) swap(str[i], str[len-1-i]);
    }
    printf("%s\n",str);
return 0;
}

题意:一张长方形桌子的四个顶点全部在整数点位置,桌子的四条边上每个整数点(x,y) (x,y都是整数)位置有一把椅子,代表有一个人,当使用加热器在桌子周围加热时,问有几个人不在加热范围之内。

输入时每组数据首先给出两个点的坐标,代表一张桌子的对角线的端点,桌子的边与坐标轴平行,然后输入一个n,代表有n个加热器,接下来n行每行输入三个数x,y,r,代表这个加热器的坐标和加热半径。

解题思路:一个加热器可以确定一个圆,判断每个人是否在圆内或圆上;输出不在圆内或圆上的人的个数即可。

#include<stdio.h>  
#include<string.h>  
int n,i,j,t,cnt,sum,x1,x2,y1,y2;  
struct radiator  
{  
    int x;  
    int y;  
    int r;  
}a[1005];  
void dis(int X,int Y) /*判断是否在圆内或圆上*/  
{  
     sum++; /*记录桌子周围的总人数*/  
     for(t=0;t<n;t++)  
     if((X-a[t].x)*(X-a[t].x)+(Y-a[t].y)*(Y-a[t].y)<=a[t].r*a[t].r)  
     {  
        cnt++;  /*记录在圆内或圆上的人的个数*/  
        break;  
     }  
}  
void cal1(int m,int p,int q)  /**/  
{  
    for(i=m,j=p;i<=q;i++)  
        dis(i,j);  
}  
void cal2(int m,int p,int q) /**/  
{  
    for(j=m,i=p;j<=q;j++)  
       dis(i,j);  
}  
int main()  
{  
    int temp1,temp2;  
    while(~scanf("%d%d%d%d",&x1,&y1,&x2,&y2))  
    {  
        if(x1>x2)   
        {  
            temp1=x1;x1=x2;x2=temp1;  
            temp2=y1;y1=y2;y2=temp2;  
        }  /*保证x1<x2*/  
        sum=0;  
        cnt=0;  
        scanf("%d",&n);  
        for(i=0;i<n;i++)  
          scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].r);  
        cal1(x1,y1,x2); /*和x轴平行的边上的点*/  
        cal1(x1,y2,x2); /*和x轴平行的边上的点*/  
        if(y1>y2)  
        {  
            cal2(y2+1,x1,y1-1); /*和y轴平行的边上的点*/  
            cal2(y2+1,x2,y1-1); /*和y轴平行的边上的点*/  
        }  
        else  
        {  
            cal2(y1+1,x1,y2-1); /*和y轴平行的边上的点*/  
            cal2(y1+1,x2,y2-1); /*和y轴平行的边上的点*/  
        }  
        printf("%d\n",sum-cnt);  
    }  
    return 0;  
}  
A. Plug-in
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

Polycarp thinks about the meaning of life very often. He does this constantly, even when typing in the editor. Every time he starts brooding he can no longer fully concentrate and repeatedly presses the keys that need to be pressed only once. For example, instead of the phrase "how are you" he can type "hhoow aaaare yyoouu".

Polycarp decided to automate the process of correcting such errors. He decided to write a plug-in to the text editor that will remove pairs of identical consecutive letters (if there are any in the text). Of course, this is not exactly what Polycarp needs, but he's got to start from something!

Help Polycarp and write the main plug-in module. Your program should remove from a string all pairs of identical letters, which are consecutive. If after the removal there appear new pairs, the program should remove them as well. Technically, its work should be equivalent to the following: while the string contains a pair of consecutive identical letters, the pair should be deleted. Note that deleting of the consecutive identical letters can be done in any order, as any order leads to the same result.

Input

The input data consists of a single line to be processed. The length of the line is from 1 to 2·105 characters inclusive. The string contains only lowercase Latin letters.

Output

Print the given string after it is processed. It is guaranteed that the result will contain at least one character.

题意:对字符串的处理,把相邻且相同的两个字符同时去掉,直到没有相邻且相同的字符为止
#include<stdio.h>
#include<cstdlib>
#include<string.h>
char a[200010];
int main()
{
	while(~scanf("%s",a))
	{
		int j=1;
		int n=strlen(a);
		for(int i=1; i<n; i++)
		{
			if(a[i]==a[j-1])  //相邻的字母相等
			{
				j--;       //j--便不会让去掉中间的字母后,对两边的字母造成影响
				a[j]='\0';//去掉已经保存在数组中的那个字母
			}
			else               //相邻的字母不等
			{
				a[j++]=a[i]; //如果相邻字母不等的话,就把当前字母也保存在数组
			}
		}
		a[j]='\0';//如果连续多个相同字母,因为遇到'\0'就停下
		printf("%s\n",a);
		
	}
	return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值