益智!!!

目录

1.拼数

2.打字练习

3.幂次方

4.【模板】字符串哈希

5.统计将重叠区间合并成组的方案数

6.DNA sequence

7.访问完所有房间的第一天

8.归并排序

9.逆序对

10.链表之队列安排

11.博弈之三国游戏

12.需要添加的硬币的最小数量


1.拼数

输入:

3
13 312 343

输入:

4
7 13 4 246
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
bool cmp(string a,string b){
	return a+b>b+a;
}

int main(){
	int n;
	cin >> n;
	string a[n];
	for (int i = 0;i<n;i++) cin >> a[i];
	sort(a,a+n,cmp);
	for (int i = 0;i<n;i++){
		cout << a[i];
	}
	cout << endl;
	return 0;
}

2.打字练习

输入:

hello world.
aaabbbb
x
EOF
heelo world.
aaacbbbb
y<x
EOF
60

#include<bits/stdc++.h>
using namespace std;
long long hs,es,cds,rig,kpm;
double t;
char s[100005];
stack<char>s1[10005],s2;
int main(){
    while(1){
        gets(s);
        cds=strlen(s);
        if(cds==3&&s[0]=='E'&&s[1]=='O'&&s[2]=='F')break;
        hs++;
        for(int i=0;i<cds;i++){
            if(s[i]=='<'&&s1[hs].empty()==0)s1[hs].pop();
            else if((s[i]>='a'&&s[i]<='z')||s[i]==' '||s[i]=='.')s1[hs].push(s[i]);
        }
    }
    while(1){
        gets(s);
        cds=strlen(s);
        if(cds==3&&s[0]=='E'&&s[1]=='O'&&s[2]=='F')break;
        es++;
        for(int i=0;i<cds;i++){
            if(s[i]=='<'&&s2.empty()==0)s2.pop();
            else if((s[i]>='a'&&s[i]<='z')||s[i]==' '||s[i]=='.')s2.push(s[i]);
        }
        stack<char>t1,t2;
        while(s1[es].empty()==0){
        	t1.push(s1[es].top());
        	s1[es].pop();
		}
		while(s2.empty()==0){
			t2.push(s2.top());
			s2.pop();
		}
		cds=min(t1.size(),t2.size());
        for(int i=1;i<=cds;i++){
            if(t1.top()==t2.top())rig++;
            t1.pop();
            t2.pop();
        }
    }
    cin>>t;
    kpm=rig*60.0/t+0.5;
    cout<<kpm<<endl;
    return 0;
}

3.幂次方

输入:

1315

输出:

2(2(2+2(0))+2)+2(2(2+2(0)))+2(2(2)+2(0))+2+2(0)

#include<iostream>
#include<cmath>
using namespace std;
int a;
void fff(int x)
{
    for(int i=14;i>=0;i--) //两万的数据最多是2(14)
    {
        if(pow(2,i)<=x){
        //pow(n,m)在cmath库中,返回n^m;枚举出第一个幂次方
            if(i==1) cout<<"2"; //2(1)不用再往后分解了且2^1输出为2,单独出来
            else if(i==0) cout<<"2(0)"; //2(0)也不用再往后分解了,单独出来
            else{ //若i>1则继续分解指数i
                cout<<"2(";
            fff(i);
            cout<<")";
            }
            x-=pow(2,i); //继续循环分解余下的
            if(x!=0) cout<<"+";
            //加号处理的最简单方法:若此x还没分解完,则后面还有项,所以输出一个+号
        }
    }
}
int main()
{
    cin>>a;
    fff(a);
    return 0;
}

4.【模板】字符串哈希

输入:

5
abc
aaaa
abc
abcc
12345

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
map<string,int>a; //map定义,相当于数组的升级版,表示string到int的映射,举个简单例子,可以用a["OK"]=1;进行赋值(说白了就是括号里的数据类型是map<>前面的,=的后面就是map<>后面的数据类型)
string s;//用于读入的字符串
int n,m;
int main(){
    cin>>n;
    m=n;
    while(n--){//因为是n+m就可以了,所以直接n--,--QWQ
    	cin>>s;
    	if(a[s]==1)m--;
    	else
    	a[s]=1;
    }
printf("%d",m);
	return 0;//完美的过程,不是吗?
}

5.统计将重叠区间合并成组的方案数

力扣!

class Solution {
public:
    static constexpr int mod = 1e9 + 7;
    int countWays(vector<vector<int>>& ranges) {
        sort(ranges.begin(), ranges.end());
        int n = ranges.size();
        long long res = 1;
        for (int i = 0; i < n; ) {
            int r = ranges[i][1];
            int j = i + 1;
            while (j < n && ranges[j][0] <= r) {
                r = max(r, ranges[j][1]);
                j++;
            }
            res = res * 2 % mod;
            i = j;
        }
        return res;
    }
};

作者:力扣官方题解
链接:https://leetcode.cn/problems/count-ways-to-group-overlapping-ranges/solutions/2706464/tong-ji-jiang-zhong-die-qu-jian-he-bing-be3bs/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

6.DNA sequence

输入:

1
4
ACGT
ATGC
CGTT
CAGT
#include<bits/stdc++.h>
using namespace std;
int t,n;
char s[10][10];
int length;
int ans;
char d[5]= {'A','C','G','T'};
void dfs(int sum,int len[]) {
	if(sum>length)
		return;
	int maxn=0;
	for(int i=0; i<n; i++) {
		if(strlen(s[i]) - len[i]>maxn)
			maxn=strlen(s[i]) - len[i];
	}
	if(maxn==0) {
		ans=sum;
		return;
	}
	if(sum+maxn>length)
		return;
	for(int i=0; i<4; i++) {
		int flag=0;
		int pos[10];
		for(int j=0; j<n; j++) {
			if(s[j][len[j]]==d[i]) {
				flag=1;
				pos[j]=len[j]+1;
			} else {
				pos[j]=len[j];
			}
		}
		if(flag)
			dfs(sum+1,pos);
		if(ans!=-1)
			return;
	}
}
int main() {
	scanf("%d",&t);
	while(t--) {
		scanf("%d",&n);
		length=0;
		for(int i=0; i<n; i++) {
			scanf("%s",s[i]);
			if(strlen(s[i])>length)
				length=strlen(s[i]);
		}
		ans=-1;
		int pos[10]= {0};
		while(1) {
			dfs(0,pos);
			if(ans!=-1)
				break;
			length++;
		}
		printf("%d\n",ans);
	}
	return 0;
}

真的好难!!!

7.访问完所有房间的第一天

输入:

class Solution {
public:
    int firstDayBeenInAllRooms(vector<int>& nextVisit) {
        int n = nextVisit.size();
        vector<long long> f(n);
        const int mod = 1e9 + 7;
        for (int i = 1; i < n; ++i) {
            f[i] = (f[i - 1] + 1 + f[i - 1] - f[nextVisit[i - 1]] + 1 + mod) % mod;
        }
        return f[n - 1];
    }
};

8.归并排序

输入:

5
4 2 4 5 1

#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
const int N=1e9+5;
ll a[N], b[N], ans;
void mergee(ll l, ll r) {
	if (l >= r) {  //不能再分了,直接返回。
		return ;
	}
	ll mid = (l + r) / 2;//取一个中间值
	ll i = l, j = mid + 1, tot = l;  // i是第一个序列的开头,j是第二个序列的开头,tot是整个的大序列。
	while (i <= mid && j <= r) {  //合并
		if (a[i] <= a[j]) {  //谁小就把谁放到前面。
			b[tot++] = a[i]; 
			i++;
		} else {
			b[tot++] = a[j];
			j++;
		}
	}
	while (i <= mid) {  //可能还没有放完,就把剩下的放进来。
		b[tot++] = a[i];
		i++;
	}
	while (j <= r) {  // 同上
		b[tot++] = a[j];
		j++;
	}
	for (int i = l; i <= r; i++) {  // 给最终的答案数组赋值。
		a[i] = b[i];
	}
	return;
}
void mergesort(ll l, ll r) {
	if (l < r) {
		int mid = (l + r) / 2;
		mergesort(l, mid);  //  先给左子序列排序。
		mergesort(mid + 1, r); //再给右子序列排序。
		mergee(l, r);  // 最后把两个子序列合并。
	}
}
int main() {
	ll n;
	cin>>n;
	for (int i = 1; i <= n; i++) {
		cin>>a[i];
	}
	mergesort(1, n);
	for (int i=1;i<=n;i++){
		cout<<a[i]<<" ";
	}
	return 0;
}

9.逆序对

输入:

6
5 4 2 6 3 1


#include<cstdio>
#include<iostream>
using namespace std;
const int N=5e5+5;
int n,a[N],c[N];
long long ans;

void msort(int b,int e)//归并排序
{
    if(b==e)  
		return;
    int mid=(b+e)/2,i=b,j=mid+1,k=b;
    msort(b,mid);
	msort(mid+1,e);
    while(i<=mid&&j<=e)
    	if(a[i]<=a[j])
    		c[k++]=a[i++];
    	else
    		c[k++]=a[j++],ans+=mid-i+1;//统计答案
    while(i<=mid)
    	c[k++]=a[i++];
    while(j<=e)
    	c[k++]=a[j++];
    for(int l=b;l<=e;l++)
    	a[l]=c[l];
} 

int main()
{
    scanf("%d",&n); 
    for(int i=1;i<=n;i++)
    	scanf("%d",&a[i]);
    msort(1,n);
    printf("%lld",ans);
    return 0;
}

10.链表之队列安排

输入:

4
1 0
2 1
1 0
2
3
3

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
using namespace std;
const int mx=1e5+10;
int n,m;
struct T{
    int l,r;        //每个同学的“左右手” 
	int d;          //表示同学是否输出 
}t[mx]={0};
void add(int i,int k,int f)       //新增同学 
{
    if(f==1)         //左 
    {
        t[k].r=t[i].r;
        t[k].l=i; 
        t[i].r=k;
        t[t[k].r].l=k;
    }
    else             //右 
    {
        t[k].r=i;
        t[k].l=t[i].l;
        t[i].l=k;
        t[t[k].l].r=k;
    }
}
int main()
{
    int x,k,f;
    cin>>n;
    t[0].r=0,t[0].l=0;
    add(0,1,1);
    for (int i=2;i<=n;i++)
    {
        cin>>x>>f;
        add(x,i,f);
    }
    cin>>m;
    while(m--)
    {
        cin>>x;
        t[x].d=1;         //将该同学标记为不输出 
    }
    for (int i=t[0].r;i;i=t[i].r)
    {
        if (t[i].d==0)    //输出未标记的 
          cout<<i<<" ";
    }
    return 0;
}

11.博弈之三国游戏

输入:

6 
5 28 16 29 27 
23 3 20 1 
8 32 26 
33 11 
12 
8 
42 24 10 29 27 12 58 
31 8 16 26 80 6 
25 3 36 11 5 
33 20 17 13 
15 77 9 
4 50 
19 

#include<cstdio>
#include<algorithm>
using std::sort;
int a[510][510];
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<n;i++)
        for(int j=i+1;j<=n;j++)
        {
            scanf("%d",&a[i][j]);
            a[j][i]=a[i][j];
        }
    int ans=0;
    for(int i=1;i<=n;i++)
    {
        sort(a[i]+1,a[i]+1+n);
        ans=ans>a[i][n-1]?ans:a[i][n-1];//选出排名第二中最大的那个
    }
    printf("1\n%d\n",ans);//一定有解
    return 0;
}

12.需要添加的硬币的最小数量

答案

class Solution:
    def minimumAddedCoins(self, coins: List[int], target: int) -> int:
        coins.sort()
        ans, s, i = 0, 1, 0
        while s <= target:
            if i < len(coins) and coins[i] <= s:
                s += coins[i]
                i += 1
            else:
                s *= 2  # 必须添加 s
                ans += 1
        return ans

作者:灵茶山艾府
链接:https://leetcode.cn/problems/minimum-number-of-coins-to-be-added/solutions/2551707/yong-gui-na-fa-si-kao-pythonjavacgo-by-e-8etj/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

小结:兽人永不为奴隶!

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值