题目:
你的王国里有一条n个头的恶龙,你希望雇佣一些骑士把它杀死(也就是砍掉所有的头)。
村里有m个骑士可以雇佣,一个能力值为 x 的骑士可以砍掉恶龙一个直径不超过 x 的头,且需要报酬 x 个金币。
如何雇佣骑士才能砍掉恶龙所有的头,并且支付最小的金币?
注意,一个骑士只能砍一个头并且仅能被雇佣1次。
要点总结:
采用贪心策略,把龙和人都升序排列,从代价最低的龙开始遍历,因为低的挑选空间最多,最可以选能力值高不出它太多的人。用一个指针指向龙,找到的第一个能满足的人用来砍他,最后指针没移到最后就是无解。
代码:
#include<bits/stdc++.h>
using namespace std;
int main(){
int n,m;
while(cin>>n>>m){
vector<int> head(n);
vector<int> nengli(m);
for(int i=0;i<n;i++){
cin>>head[i];
}
for(int i=0;i<m;i++){
cin>>nengli[i];
}
sort(head.begin(),head.end());
sort(nengli.begin(),nengli.end());
int p=0;
int cost=0;
for(int i=0;i<m;i++){
if(p<n&&nengli[i]>=head[p]){
cost+=nengli[i];
p++;
}
}
if(p!=n){
cout<<"Lose!"<<endl;
}else{
cout<<cost<<endl;
}
}
return 0;
}
题目:
输出这样的方针
1 2 3 4 5 6 7 8 9 10 11
22 21 20 19 18 17 16 15 14 13 12
23 24 25 26 27 28 29 30 31 32 33
44 43 42 41 40 39 38 37 36 35 34
45 46 47 48 49 50 51 52 53 54 55
66 65 64 63 62 61 60 59 58 57 56
67 68 69 70 71 72 73 74 75 76 77
88 87 86 85 84 83 82 81 80 79 78
89 90 91 92 93 94 95 96 97 98 99
110 109 108 107 106 105 104 103 102 101 100
111 112 113 114 115 116 117 118 119 120 121
要点总结:
嵌套循环去给二维数组填值,在每一行开始根据行数设置一个base值,然后根据行数的奇偶从判断填充方向。
代码:
#include<bits/stdc++.h>
using namespace std;
int main(){
int n;
cin>>n;
vector<vector<int>> arr(n+1,vector<int> (n+1));
for(int i=1;i<=n;i++){
int base=n*(i-1)+1;
for(int j=1;j<=n;j++){
if(i%2==0){
arr[i][j]=base+n-j;
}else{
arr[i][j]=base+j-1;
}
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cout<<right<<setw(4)<<arr[i][j];
}
cout<<endl;
}
return 0;
}
题目:
输入两个字符串,获取两个字符串中最长相同子串并输出。
如果有多个相同子串,则输出(按ASCII排序)最小的那个"最长相同子串"。
如果无相同子串,则输出空字符串(即空行)。
要点总结:
对其中一串遍历所有的开始顶点以及子串长度,截取出来之后到另外一个串里面去find,找到就不是-1,中间维护一下最大长度方便剪枝
代码:
#include<bits/stdc++.h>
using namespace std;
int main(){
string a,b;
while(getline(cin,a)){
getline(cin,b);
int maxlen=INT_MIN;
string res="";
for(int start=0;start<a.size();start++){
for(int len=1;len<=a.size()-start;len++){
if(len<maxlen) continue;
string cur=a.substr(start,len);
if(b.find(cur)==-1){
continue;
}
if(len>maxlen){
res=cur;
maxlen=len;
}else{
res=min(res,cur);
}
}
}
if(res==""){
cout<<endl;
}else{
cout<<res<<endl;
}
}
return 0;
}
题目:
我们知道,整数做除法时,有时得到有限小数,有时得到无限循环小数。
如果我们把有限小数的末尾加上无限多个0,它们就有了统一的形式。
本题的任务是:在上面的约定下,求整数除法小数点后的第n位开始的3位数。
要点总结:
不要被吓住了去真的区分循环还是不循环,这里直接把前面n-1位除完后的余数先算出来,然后再拿余数算三次值就好了。
代码:
#include<bits/stdc++.h>
using namespace std;
int main(){
long long a,b,n;
cin>>a>>b>>n;
long long remainder=a%b;
for(int i=0;i<n-1;i++){
remainder=(remainder*10)%b;
}
for(int i=0;i<3;i++){
cout<<(remainder*10)/b;
remainder=(remainder*10)%b;
}
return 0;
}
题目:
给定一个长度为n的字符串S,还有一个数字L,统计长度大于等于L的出现次数最多的子串(不同的出现可以相交),如果有多个,输出最长的,如果仍然有多个,输出第一次出现最早的。
要点总结:
用一个map去记录字符串以及其出现的次数,遍历截取所有字串记录之后,设置题目要求的三个判断的全局变量,遍历map去更新全局变量。注意,一定是isbest为true之后把三个一起更新,不要写在给它赋true的那个语句块里,不然集众家所长了。
代码:
#include<bits/stdc++.h>
using namespace std;
int main(){
int L;
string s;
cin>>L>>s;
map<string,int> record;
for(int len=L;len<=s.size();len++){
for(int start=0;start<=s.size()-len;start++){
string cur=s.substr(start,len);
record[cur]++;
}
}
int maxtime=INT_MIN;
int maxlen=INT_MIN;
int start_pos=INT_MAX;
string res;
for(auto x : record){
bool isbest=false;
int curtime=x.second;
int curlen=x.first.size();
int curpos=s.find(x.first);
if(curtime>maxtime){
isbest=true;
}else if(curtime==maxtime){
if(curlen>maxlen){
isbest=true;
}
else if(curlen==maxlen){
if(curpos<start_pos){
isbest=true;
}
}
}
if(isbest){
res=x.first;
maxtime=curtime;
maxlen=curlen;
start_pos=curpos;
}
}
cout<<res;
return 0;
}
题目:
在C/C++语言中,整型所能表示的范围一般为-231到231(大约21亿),即使long long型,一般也只能表示到-263到263。要想计算更加规模的数,就要用软件来扩展了,比如用数组或字符串来模拟更多规模的数及共运算。
现在输入两个整数,请输出它们的乘积。
要点总结:
这个相乘的两个数都很大,不能像阶乘那道用一个数乘了去进位。要模拟竖式的计算,用两个字符串读进来之后从末尾开始遍历,i和j只要有一个小了1就是往前推1位,在每一步里面算一下当前的和以及下一位的进位。最后前面为0的不要输出。还有就是算进位的时候记得是累加,不要直接相等,那样会覆盖其他时候算的进位。这里面都记得char要转int,别忘记了。
代码:
#include<bits/stdc++.h>
using namespace std;
int main(){
string a,b;
cin>>a>>b;
int m=a.size();
int n=b.size();
int res[m+n];
for(int i=0;i<(m+n);i++){
res[i]=0;
}
for(int i=m-1;i>=0;i--){
int x=a[i]-'0';
for(int j=n-1;j>=0;j--){
int y=b[j]-'0';
int mul=x*y;
int curidx=i+j+1;
int nextidx=i+j;
int sum=mul+res[curidx];
res[curidx]=sum%10;
res[nextidx]+=sum/10;
}
}
int start;
for(int i=0;i<(m+n);i++){
if(res[i]!=0) {
start=i;
break;
}
}
for(int i=start;i<(m+n);i++){
cout<<res[i];
}
return 0;
}
题目:
给定n和len,输出n!末尾len位。
要点总结:
这个n在10000以内,就诸位乘了进位。要注意的是实际结果可能比len段,所以长度得取小一下,然后反着取出来转char拼到string上,最后补一下0输出。
代码:
#include<bits/stdc++.h>
using namespace std;
int main(){
int n,len;
cin>>n>>len;
vector<int> res;
res.push_back(1);
for(int i=2;i<=n;i++){
int jin=0;
for(int j=0;j<res.size();j++){
int num=res[j]*i+jin;
int cur=num%10;
jin=num/10;
res[j]=cur;
}
while(jin>0){
int num=jin%10;
res.push_back(num);
jin=jin/10;
}
}
int size=res.size();
int slen=min(len,size);
string s="";
for(int i=slen-1;i>=0;i--){
char a='0'+res[i];
s=s+a;
}
cout<<setw(len)<<setfill('0')<<s;
return 0;
}
题目:
道德经曰:一生二,二生三,三生万物。
对于任意正整数n,我们定义d(n)的值为为n加上组成n的各个数字的和。例如,d(23)=23+2+3=28, d(1481)=1481+1+4+8+1=1495。
因此,给定了任意一个n作为起点,你可以构造如下一个递增序列:n,d(n),d(d(n)),d(d(d(n)))....例如,从33开始的递增序列为:
33, 39, 51, 57, 69, 84, 96, 111, 114, 120, 123, 129, 141, ...
我们把n叫做d(n)的生成元,在上面的数列中,33是39的生成元,39是51的生成元,等等。有一些数字甚至可以有两个生成元,比如101,可以由91和100生成。但也有一些数字没有任何生成元,如42。我们把这样的数字称为寂寞的数字。
要点总结:
此题不用纠结去递归的掉d的函数,只需要把所有小于n的数算d就可以,然后用bool数组标记一下,输出所有在n以内没有标记的。因为所有小于n的不寂寞的数都要由小于n的正整数通过d生成,不会漏情况。
代码:
#include<bits/stdc++.h>
using namespace std;
int getd(int n){
int res=n;
while(n>0){
res+=n%10;
n/=10;
}
return res;
}
int main(){
int n;
cin>>n;
bool visited[15000]={false};
for(int i=1;i<=n;i++){
int x=getd(i);
visited[x]=true;
}
for(int i=1;i<n;i++){
if(!visited[i]){
cout<<i<<endl;
}
}
return 0;
}
英语翻译:
多模态学习是人工智能领域一个重要的研究方向,其旨在使模型能够同时处理不同种类的数据,例如文本,图像以及语音。在真实世界中,人们通过多种感官获取信息,所以单一模态的数据通常不能完整表达复杂的情景。多模态学习将不同模态的信息整合起来,使模型获得更加综合的理解能力。例如,在图像描述任务中,模型可以理解视觉内容并且相应地生成文本描述。随着深度学习技术的发展,多模态模型已经在很多领域取得了显著的进展。例如视觉回答、跨模态检索以及智能人工助手
