**题目描述
临近开学了,小C才想起来数学老师布置了暑假作业。暑假作业是很多张试卷,每张试卷所需的时间和获取的价值已知,请你帮他安排一下,用他仅剩的一点时间来做最有价值的作业。
接口说明
原型:
int GetMaxValue(int nPapers, int nRemain, int paper[][2], double* pMaxValue)
输入参数:
int nPapers:试卷的数目(1≤Papers≤20)
int nRemain:表示剩余的时间(1≤nRemain≤10000)
int paper[][2]:nPapers*2的数组,每一行的两个元素依次为做完这一份试卷所需的时间、做完这份试卷获取的价值。如果剩余时间不够做完一份卷子,可根据剩余时间获得卷子的部分价值。
输出参数:
double * pMaxValue:获得的最大价值
返回值:
0:异常,1:成功
题目理解:由于题目说试卷时间可分割,因此这就可以当成可划分的背包问题,可以利用贪心算法来解。
**
#include "OJ.h"
#include <algorithm>
void bubbleSort(int paper[][2],int nPapers);
int GetMaxValue(int nPapers, int nRemain, int paper[][2], double* pMaxValue)
{
if(nPapers<0||nRemain<0||paper==NULL||pMaxValue==NULL) return 0;
bubbleSort(paper,nPapers);
*pMaxValue=0;
for(int i=0; i<nPapers; i++){
if(nRemain>0){
if(nRemain>=paper[i][0]){
*pMaxValue += paper[i][1];
nRemain -= paper[i][0];
}else{
*pMaxValue += (paper[i][1]*1.0 / paper[i][0]) * nRemain;
nRemain=0;
}
}else break;
}
return 1;
}
//从大到小冒泡排序
void bubbleSort(int paper[][2],int nPapers){
for(int i=0; i<nPapers; i++){
for(int j=0; j<nPapers-i-1; j++){
double db1,db2;
int temp;
db1= paper[j][1]*1.0/paper[j][0];
db2= paper[j+1][1]*1.0/paper[j+1][0];
if(db2 > db1){
temp=paper[j][0];
paper[j][0]=paper[j+1][0];
paper[j+1][0]=temp;
temp=paper[j][1];
paper[j][1]=paper[j+1][1];
paper[j+1][1]=temp;
}
}
}
}
**题目描述
如果一个字符串可以由某个长度为k的字符串重复多次得到,我们说该串以k为周期。例如,abcabcabcabc以3为周期(注意,它也可以6和12为周期,结果取最小周期3)。字符串的长度小于等于100,由调用者保证。
详细描述:
接口说明
原型:
int GetMinPeriod(char *inputstring);
输入参数:
char * inputstring:字符串
返回值:
int 字符串最小周期**
理解:利用周期性的特点,字符串左移或者右移n个周期,其对应位置的值不变。如
abcabcabc
abcabcabc右移三位
#include "OJ.h"
#include <string.h>
int GetMinPeriod(char *inputstring)
{
if(inputstring ==NULL) return -1;
int count=1;
int len = strlen(inputstring);
if(len==1) return 1;
int j;
for(count=1;count<=len/2+1; count++){
for(j=count; j<len; j++){
if(inputstring[j]!=inputstring[j-count]) break;
}
if(j==len) return count;
}
return len;
}
**密码要求:
1.长度超过8位
2.包括大小写字母.数字.其它符号,以上四种至少三种
3.不能有相同长度超2的子串重复
说明:长度超过2的子串**
样例输入:
021Abc9000
021Abc9Abc1
021ABC9000
021$bc9000
样例输出:
OK
NG
NG
OK
'注意:由于输入为多行,要使用getline读取输入数据否则极易出错'
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <stdlib.h>
using namespace std;
int judgeCode(string &code);
int main(){
string code;
string temp;
//vector<string> result;
string s1;
vector<string> s;
while (getline(cin,s1))
{
if (judgeCode(s1)==0)
//tmpstr="OK";
cout<<"OK"<<endl;
else
cout<<"NG"<<endl;
}
return 0;
}
int judgeCode(string &code){
int len=code.size();
if(len<8) return 1;
int characters[4]={0}; // A a 0 $
for(int i=0; i<len; i++){
if(code[i]<='Z'&&code[i]>='A') characters[0]=1;
else if(code[i]<='z'&&code[i]>='a') characters[1]=1;
else if(code[i]<='9'&&code[i]>='0') characters[2]=1;
else characters[3]=1;
}
int sum=0;
for(int i=0;i<4;i++) sum +=characters[i];
if(sum<3) return 1;
//查找重复子串
vector<string> temp;
//截取所有长度大于等于3的子串
string sub_str;
for(int subLen=3;subLen<=len; subLen++){
for(int i=0;i<=len-subLen;i++){
temp.push_back(code.substr(i,subLen));
}
}
vector<string>::iterator tmp_iter;
for(tmp_iter=temp.begin(); tmp_iter!=temp.end(); tmp_iter++){
if(code.find(*tmp_iter)!=code.rfind(*tmp_iter)) return 1;
}
return 0;
}
有n个人围成一圈,顺序排号。从第一个人开始报数(从1到3报数),凡报到3的人退出,问最后留下的那位是原来第几号。
下面是使用链表处理该问题的,其实该问题可以使用数组处理,方法会比较简单。
#include <iostream>
#include <algorithm>
#include <string>
#include <algorithm>
using namespace std;
typedef struct List{
int num;
struct List *next;
} List;
void generateList(List **head,int n){
List *tail=NULL;
*head=new List;
(*head)->next=*head;
(*head)->num=1;
tail=*head;
List *temp=NULL;
for(int i=2; i<=n;i++){
temp= new List;
temp->next=*head;
temp->num =i;
tail->next = temp;
tail =temp;
}
}
int main(){
int count=0;
cin>>count;
List *head=NULL;
generateList(&head,count);
List *index=head;
List *temp=NULL;
while(index->next!= index){
index =index->next;
temp=index->next->next;
delete index->next;
index->next = temp;
index =index->next;
}
cout<<index->num<<endl;
delete index;
system("pause");
return 0;
}
**
给定一个正整数N代表火车数量,N在0到10之间,不包括0和10,,接下来输入火车入站的序列,一共N辆火车,每辆火车以数字1-9编号。要求以字典序排序输出火车出站的序列号。
**
算法思想,首先计算出输入序列的全排列,然后利用栈的特点“任何在当前元素之后输出,且比该元素小的数,一定是逆序的
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
int JudgeTrainSequence (string& str);
int main()
{
int num;
string str="ABCDEFGHIJ",a;
vector<string> tmp;
cin>>num;
getchar();
getline(cin,a);
str=str.substr(0,num);
tmp.push_back(str);
while(next_permutation(str.begin(),str.end()))
tmp.push_back(str);//得到了全排列
vector<string>::iterator tmp_iter=tmp.begin();
for (;tmp_iter!=tmp.end();)
{
string s=*tmp_iter;
int len=s.size();
string::iterator s_iterator=s.begin()+1;
while(s_iterator<s.end())
{
char ch=*(s.begin());
if (*s_iterator>*(s.begin()))
{
s.erase(s_iterator);
}else s_iterator++;
}
string q=s;
sort(s.rbegin(),s.rend());
if(q!=s) //判断是非满足出栈条件
tmp_iter=tmp.erase(tmp_iter);
else tmp_iter++;
}
for(int j=0;j<tmp.size();j++)
for (int i=0;i<num;i++)
replace(tmp[j].begin(),tmp[j].end(),str[i],a[i*2]);
sort(tmp.begin(),tmp.end());
for (int i=0;i<tmp.size();i++)
{
string m;
m=tmp[i];
for (int k=0;k<m.size();k++)
{
cout<<m[k];
if(k==m.size()-1)
cout<<endl;
else
cout<<" ";
}
}
system("pause");
return 0;
}
int JudgeTrainSequence (string& str)
{
int len=str.length();
for(int i=0; i<len-1; i++){
int max=str[i];
int sw=0;
for(int j=i+1; j<len; j++){
if(str[j]<max){
if(sw==0){
max=str[j];
}
sw=1;
if(str[j]>max) return 0;
}
}
}
return 1;
}
实现输入一组大于等于0的整数,根据从小到大的顺序排序后输出,排序后有连续数时,只输出连续数中最小和最大的两个数。
#include <iostream>
#include <algorithm>
#include <string>
#include <algorithm>
using namespace std;
int main(){
int num[100]={0};
string str;
cin>>str;
int temp=0;
int j=0;
for(int i=0; i< str.length(); i++){
if(str[i]!=','){
temp =temp*10 + (str[i]-'0');
}else{
num[j++]=temp;
//cout<<num[j-1]<<' ';
temp=0;
}
}
num[j]=temp;
sort(num,num+j+1);
cout<<num[0]<<' ';
int flag=0;
for(int i=1; i<=j; i++){
if(num[i]-num[i-1] == 1){
//i++;
flag=1;
}
else{
if(flag==1){
cout<<num[i-1]<<' '<<num[i]<<' ';
flag=0;
}
else cout<<num[i]<<' ';
}
}
if(flag==1) cout<<num[j];
cout<<endl;
system("pause");
return 0;
}
**密码是我们生活中非常重要的东东,我们的那么一点不能说的秘密就全靠它了。哇哈哈. 接下来渊子要在密码之上再加一套密码,虽然简单但也安全。
假设渊子原来一个BBS上的密码为zvbo9441987,为了方便记忆,他通过一种算法把这个密码变换成YUANzhi1987,这个密码是他的名字和出生年份,怎么忘都忘不了,而且可以明目张胆地放在显眼的地方而不被别人知道真正的密码。
他是这么变换的,大家都知道手机上的字母: 1–1, abc–2, def–3, ghi–4, jkl–5, mno–6, pqrs–7, tuv–8 wxyz–9, 0–0,就这么简单,渊子把密码中出现的小写字母都变成对应的数字,数字和其他的符号都不做变换,
声明:密码中没有空格,而密码中出现的大写字母则变成小写之后往后移一位,如:X,先变成小写,再往后移一位,不就是y了嘛,简单吧。记住,z往后移是a哦。**
//简单密码破解
#include <iostream>
#include <algorithm>
#include <string>
#include <algorithm>
using namespace std;
int main(){
string namestr;
cin>>namestr;
for(int i=0; i<namestr.length(); i++){
switch(namestr[i]){
case 'a':
case 'b':
case 'c':
namestr[i]='2';
break;
case 'd':
case 'e':
case 'f':
namestr[i]='3';
break;
case 'g':
case 'h':
case 'i':
namestr[i]='4';
break;
case 'j':
case 'k':
case 'l':
namestr[i]='5';
break;
case 'm':
case 'n':
case 'o':
namestr[i]='6';
break;
case 'p':
case 'q':
case 'r':
case 's':
namestr[i]='7';
break;
case 't':
case 'u':
case 'v':
namestr[i]='8';
break;
case 'w':
case 'x':
case 'y':
case 'z':
namestr[i]='9';
break;
default:
if(namestr[i]<'Z'&&namestr[i]>='A'){
namestr[i] = namestr[i] + 'a'- 'A'+1;
}
else if(namestr[i]=='Z') namestr[i]='a';
break;
}
}
cout<<namestr<<endl;
system("pause");
return 0;
}
**计算整数的位数,并逆序输出
输入一个五位以内(包括5位)的正整数,(1)判断它是一个几位数;(2)逆序输出其各位数字。**
#include <iostream>
#include <algorithm>
#include <string>
#include <algorithm>
using namespace std;
int main(){
int num=0;
int count=0;
int temp=0;
cin>>num;
temp=num;
while(temp!=0){
temp = temp/10;
count++;
}
temp=num;
cout<<count<<' ';
while(temp!=0){
cout<<temp%10;
temp /=10;
}
cout<<endl;
system("pause");
return 0;
}
找零钱问题
我们知道人民币有1、2、5、10、20、50、100这几种面值。现在给你n(1≤n≤250)元,让你计算换成用上面这些面额表示且总数不超过100张,共有几种。比如4元,能用4张1元、2张1元和1张2元、2张2元,三种表示方法。
采用回溯法求解问题,算法思想同N皇后。
#include <stdio.h>
#include <iostream>
using namespace std;
int a[7]={1,2,5,10,20,50,100};
int temp[7]={0};
int total=0;
int count=0;
void function(int sum, int index) {
int j,i;
if (sum==total) {
int pices=0;
for(int x=0;x<7; x++) pices +=temp[x];
if(pices<=100) count++;
return;
}
else if (sum>total) return;
else{
for (i=index;i<7;i++) {
temp[i]++;
function(sum+a[i],i);
temp[i]--;
}
}
}
int main() {
cin>>total;
while(total!=0){
count=0;
function(0,0);
cout<<count<<endl;
cin>>total;
}
return 0;
}
**计算最少出列多少位同学,使得剩下的同学排成合唱队形
说明:
N位同学站成一排,音乐老师要请其中的(N-K)位同学出列,使得剩下的K位同学排成合唱队形。
合唱队形是指这样的一种队形:设K位同学从左到右依次编号为1,2…,K,他们的身高分别为T1,T2,…,TK, 则他们的身高满足存在i(1<=i<=K)使得Ti
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
int n,arr[100],answer=0;
cin>>n;
for(int i=0;i<n;i++)
cin>>arr[i];
int *listrise=new int[n]; //求最长上升子序列
for (int i=0;i<n;i++)
{
listrise[i]=1;
for (int j=0;j<i;j++)
{
if ((arr[i]>arr[j])&&(listrise[j]+1>listrise[i]))
listrise[i]=listrise[j]+1;
}
}
int *listdown=new int[n]; //求最大下降子序列
for (int i=n-1;i>=0;i--)
{
listdown[i]=1;
for (int j=n-1;j>i;j--)
{
if ((arr[i]>arr[j])&&(listdown[j]+1>listdown[i]))
listdown[i]=listdown[j]+1;
}
}
for(int i=0;i<n;i++)
if(listrise[i]+listdown[i]-1>answer)
answer=listrise[i]+listdown[i]-1;
cout<<n-answer<<endl;
system("pause");
return 0;
}
*/
//统计某个整数二进制中 0的个数
#include<iostream>
#include<stdio.h>
#include<string>
using namespace std;
int main(){
unsigned int test;
cin>>test;
int count=0;
while(test!=0){
if((test&0x1)==0) count++;
test = test>>1;
}
cout<<count<<endl;
system("pause");
return 0;
}
*/
//统计不同行字符的个数
#include<iostream>
#include<stdio.h>
#include<string>
using namespace std;
int main(){
string str;
char result[256]={0};
cin>>str;
size_t len= str.length();
if(len<=0) return 1;
//int k=0;
for(int i=0; i<len; i++){
result[str[i]]=1;
}
int count=0;
for(int j=0; j<256; j++){
if(result[j]==1) count++;
}
cout<<count<<endl;
system("pause");
return 0;
}*/
Lily上课时使用字母数字图片教小朋友们学习英语单词,每次都需要把这些图片按照大小(ASCII码值从小到大)排列收好。请大家给Lily帮忙,通过C语言解决。
输入:
Lily使用的图片包括”A”到”Z”、”a”到”z”、”0”到”9”。输入字母或数字个数不超过1024。
输出:
Lily的所有图片按照从小到大的顺序输出
样例输入:
Ihave1nose2hands10fingers
样例输出:
0112Iaadeeefghhinnnorsssv
#include<iostream>
#include<stdio.h>
#include <algorithm>
using namespace std;
int main(){
char instr[1024]={0};
scanf("%s",instr);
int len=strlen(instr);
sort(instr,instr+len);
for(int i=0; i<len; i++)
cout<<instr[i];
system("pause");
return 0;
}*/
查找出所有大于1小于等于整数m(m < 100)的非素数。 例如,若输入:17,则应输出:4 6 8 9 10 12 14 15 16。
输入:
输入一个大于1小于100的整数,如 17。
输出:
输出所有查找到的非素数。
样例输入:
17
样例输出:
4 6 8 9 10 12 14 15 16
#include<iostream>
#include<stdio.h>
using namespace std;
int main(){
int num=0;
cin>>num;
if(num<=1) return 0;
for(int i=2; i<=num; i++ ){
for(int k=2; k<i; k++)
if(i%k==0){
cout<<i<<' ';
break;
}
}
//system("pause");
return 0;
}*/
//计算最大公约数,利用辗转相除法
#include<iostream>
#include<stdio.h>
using namespace std;
int gcd(int a, int b){
int temp=0;
if(a < b){
temp=a;
a=b;
b=temp;
}
while(b!=0){
temp = a%b;
a=b;
b=temp;
}
return a;
}
int main(){
int num1,num2;
cin>>num1>>num2;
cout<<gcd(num1,num2);
// system("pause");
return 0;
}*/
N 皇后问题
#include "OJ.h"
#include<iostream>
#include<stdlib.h>
#include<stdio.h>
using namespace std;
bool find(int row, int col, int *count);
void place(int row, int n, int *q, int *count);
/*
功能: 求解放置8皇后方案的个数。
输入:
无
返回:
int:放置8皇后方案的个数
*/
int PlaceQueenMethodNum(int n)
{
/*在这里实现功能*/
int count=0;
int q[20];
place(1,n, q, &count);
return count;
}
void place(int row, int n, int *q, int *count)
{
if(row>n){
(*count)++;
return;
}
int col=0;
for(col=1; col<= n; col++){
if(find(row,col,q)){
q[row]=col;
place(row+1, n, q, count);
}
}
}
bool find(int row, int col, int *q)
{
int i=1;
while(i< row){
if(q[i] == col || abs(i-row)==abs(q[i] - col))
return false;
i++;
}
return true;
}