前面几道签到题用最近学的java写的,学得不多只能用java写前两题🤣
目录
A.小红得删字符
思路: 签到题
code
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
String s=sc.next();
for(int i=0;i<s.length();i++)
{
if(i!=1)
System.out.print(s.charAt(i));
}
// System.out.print(s);
}
}
B.小红的正整数
思路:签到题,先将字符串排序,如果有0的话就用第一个非零数与第一个零交换位置
code
import java.util.Scanner;
import java.util.Arrays;
public class Main{
public static void main(String[] args){
Scanner sc=new Scanner(System.in);
// int x; x=sc.nextInt();
String s=sc.next();
int k=s.length();
char[] c=new char[k];
for(int i=0;i<k;i++)
c[i]=s.charAt(i);
Arrays.sort(c);
int pos=0;
if(c[0]=='0')
{
for(int i=0;i<k;i++)
if(c[i]!='0')
{
pos=i;
break;
}
char t=c[0];
c[0]=c[pos];
c[pos]=t;
for(int i=0;i<k;i++)
System.out.print(c[i]);
}
else
for(int i=0;i<k;i++)
System.out.print(c[i]);
}
}
C.小红构造回文
思路:回文串根据长度分为两种情况,我们每次只需要去遍历回文的一半的长度,然后交换两个不同的字符,另一半也对应的交换两个不同的字符就可以得到一个新的回文字符串了
(1) 长度为偶数 ,例如 aaaa 它的前一半只出现了一种字符,所以无解,而aabbaa前一半出现了两种字符,位置在 a0 a2,另一半对应的位置分别为a0+(len/2-a0-1)*2+1,a2+(len/2-a2-1)*2+1.
(2) 长度为奇数 , 例如 aba 它的前一半只出现了一种字符,所以无解,而 aabcbaa 前一半出现了两种字符,位置在a0 a2 ,另一半对应的位置分别为a0+(len/2-a0)*2, a1+(len/2-a1)*2.
code:
#include <iostream>
#include <cstring>
#include <map>
#include <algorithm>
using namespace std;
const int N = 1e5+5;
pair<char,int> q[N];
int main()
{
string s;cin>>s;
map<char,int> mp;
int len=s.size()/2,k=s.size();
int cnt=0;
for(int i=0;i<len;i++)
{
if(!mp[s[i]]&&cnt<2)
{
q[cnt++]={s[i],i};
mp[s[i]]++;
}
}
if(mp.size()==1) puts("-1");
else
{
int a=q[0].second,b=q[1].second;
int a1,b1;
if(k%2==0)
a1=a+(len-a-1)*2+1,b1=b+(len-b-1)*2+1;
else a1=a+(len-a)*2,b1=b+(len-b)*2;
// cout<<a<<' '<<b<<endl<<a1<<' '<<b1<<endl;
swap(s[a],s[b]);
swap(s[a1],s[b1]);
cout<<s;
}
}
D.小红的整数操作
思路:数论中的一个定理 ——一个数a在区间[1,x]中的倍数个数为x/a个 ,我们可以先将 x,y 除以最大公约数,使它们变为最小质数,然后求l到r的最大下界和最小上界。
code:
#include <iostream>
#include <map>
#include <algorithm>
#include <cstring>
//#define int long long
using namespace std;
int32_t main()
{
int x,y,l,r;cin>>x>>y>>l>>r;
int t=__gcd(x,y);
x/=t;
y/=t;
if(x>y) swap(x,y);
int mind=(l+x-1)/x;
int maxd=r/y;
cout<<max(maxd-mind+1,0);
}
E.小红的树上染色
思路:经典的树形dp,因为只有两种状态所有我们可以设置数组f[i][2],其中f[i][0]表示第i个节点未染色的染色方案,f[i][1]表示第i个节点染色的染色方案,如果第i个节点未染色,那么子节点一定要染色,因为是状态叠加,基于乘法原理状态转移方程为f[i][0]=f[i][0]*f[son][1],若第i个节点染色,那么子节点可以染或者不染,所以状态转移方程为f[i][1]=f[i][1]*(f[son][0]+f[son][1])
code:
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#define int long long
using namespace std;
constexpr int N = 1e5+5,mod=1e9+7;
vector<int> g[N];
int f[N][2];
int n;
void dfs(int u)
{
f[u][0]=1,f[u][1]=1;
for(auto t:g[u])
{
dfs(t);
f[u][0]=(f[u][0]*f[t][1])%mod;
f[u][1]=(f[u][1]*(f[t][1]+f[t][0]))%mod;
}
}
int32_t main()
{
cin>>n;
for(int i=1;i<n;i++)
{
int a,b;cin>>a>>b;
g[a].push_back(b);
}
dfs(1);
cout<<(f[1][0]+f[1][1])%mod;
}