1、题目描述:读入两个小于10000的正整数A和B,计算A+B。需要注意的是:如果A和B的末尾K(不超过8)位数字相同,请直接输出-1。【浙江大学】
示例代码:
#include
using namespace std;
int main(){
int a, b, k, result;
int modA, modB;
while(cin >> a >> b >> k && a != 0 && b != 0){
result = a + b;
bool flag = true;
while(a > 0 && b > 0 && k > 0){
modA = a % 10;
modB = b % 10;
if(modA != modB){
flag = false;
break;
}
a /= 10;
b /= 10;
k--;
}
if(!flag){
cout << result << endl;
}else{
cout << -1 << endl;
}
}
return 0;
}
2、题目描述:The digital root of a positive integer is found by summing the digits of the integer. If the resulting value is a single digit then that digit is the digital root. If the resulting value contains two or more digits, those digits are summed and the process is repeated. This is continued as long as necessary to obtain a single digit. For example, consider the positive integer 24. Adding the 2 and the 4 yields a value of 6. Since 6 is a single digit, 6 is the digital root of 24. Now consider the positive integer 39. Adding the 3 and the 9 yields 12. Since 12 is not a single digit, the process must be repeated. Adding the 1 and the 2 yeilds 3, a single digit and also the digital root of 39.【北京大学】
示例代码:
#include
using namespace std;
int GetLocSum(int n){
if(n < 10){
return n;
}
int result = 0;
while(n != 0){
result += n % 10;
n /= 10;
}
return GetLocSum(result);
}
int main(){
int n;
while(cin >> n && n != 0){
cout << GetLocSum(n) << endl;
}
return 0;
}
3、题目描述:在某条线路上有N个火车站,有三种距离的路程,L1,L2,L3,对应的价格为C1,C2,C3.其对应关系如下: 距离s 票价 0
示例代码:
#include
#include
using namespace std;
const int MAX_N = 500;//最大为500个站
const int MAX_INT = 0x7fffffff;
int distList[MAX_N];//dist[i]表示从第i - 1到i站的距离
int l1, l2, l3, c1, c2, c3;
int dp[MAX_N];//dp[i]表示第i站下车的最小花费
int GetCost(int dist){
if(dist > 0 && dist <= l1){
return c1;
}else if(dist > l1 && dist <= l2){
return c2;
}else if(dist > l2 && dist <= l3){
return c3;
}else{
return 0;
}
}
int main(){
int begin, end, n;//begin:起始站,end:终点站,n:火车站数
int dist;//每个站之间的距离
while(cin >> l1 >> l2 >> l3 >> c1 >> c2 >> c3 >> begin >> end >> n){
memset(dp, 0, sizeof(dp));
memset(distList, 0, sizeof(distList));
int tmp = 0;
for(int i = 1; i < n; i++){
cin >> dist;
distList[i] = dist - tmp;
tmp = dist;
}
int tmpLoc;
for(int i = begin + 1; i <= end; i++){
dp[i] = MAX_INT;
tmpLoc = 0;
for(int j = i - 1; j >= begin; j--){
tmpLoc += distList[j];
if(tmpLoc > l3){
break;
}
dp[i] = min(dp[j] + GetCost(tmpLoc), dp[i]);
}
}
cout << dp[end] << endl;
}
return 0;
}
4、题目描述:有一个网络日志,记录了网络中计算任务的执行情况,每个计算任务对应一条如下形式的日志记录: “hs_10000_p”是计算任务的名称, “2007-01-17 19:22:53,315”是计算任务开始执行的时间“年-月-日 时:分:秒,毫秒”, “253.035(s)”是计算任务消耗的时间(以秒计) hs_10000_p 2007-01-17 19:22:53,315 253.035(s) 请你写一个程序,对日志中记录计算任务进行排序。 时间消耗少的计算任务排在前面,时间消耗多的计算任务排在后面。 如果两个计算任务消耗的时间相同,则将开始执行时间早的计算任务排在前面。【北京大学】
示例代码1:
#include
#include
#include
#include
using namespace std;
struct Node{
string str;
string name;
string day;
string time;
double mTime;
Node(string s):str(s){};
};
bool CompareDesc(const Node &n1, const Node &n2){
if(n1.mTime == n2.mTime){
if(n1.day == n2.day){
return n1.time < n2.time;
}
return n1.day < n2.day;
}
return n1.mTime < n2.mTime;
}
string GetString(string s, int &index, int len){
string result = "";
while(index < len && s[index] != ' '){
result += s[index++];
}
return result;
}
double StringTodouble(string s, int len){
int frontResult = 0, backResult = 0;
int pointLoc = s.find('.');
int index = 0;
if(pointLoc != s.npos){ //有小数点
while(index < pointLoc){
frontResult = frontResult * 10 + s[index++] - '0';
}
index++;
}
while(index < len){
backResult = backResult * 10 + s[index++] - '0';
}
return frontResult + backResult / 1000.0;
}
int main(){
vector nodeList;
string s;
while(getline(cin , s)){
int index = 0, len = s.size(), paramNum = 1;
Node node = Node(s);
while(index < len){
if(s[index] != ' '){
string paramStr = GetString(s, index, len);
if(paramNum == 1){
node.name = paramStr;
}else if(paramNum == 2){
node.day = paramStr;
}else if(paramNum == 3){
node.time = paramStr;
}else if(paramNum == 4){
int len2 = paramStr.size() - 3;
node.mTime = StringTodouble(paramStr.substr(0, len2), len2);
}
paramNum++;
}else{
index++;
}
}
nodeList.push_back(node);
}
sort(nodeList.begin(), nodeList.end(), CompareDesc);
for(int i = 0; i < nodeList.size(); i++){
cout << nodeList[i].str << endl;
}
return 0;
}
示例代码2(使用sscanf):
#include
#include
#include
#include
using namespace std;
struct Node{
char str[100];
char name[11];
char day[30];
char time[20];
double mTime;
}nodeList[10000];
bool CompareDesc(const Node &n1, const Node &n2){
if(n1.mTime == n2.mTime){
if(strcmp(n1.day, n2.day) == 0){
return strcmp(n1.time, n2.time) < 0;
}
return strcmp(n1.day, n2.day) < 0;
}
return n1.mTime < n2.mTime;
}
double CharArrayTodouble(char s[]){
int len = strlen(s) - 3;
int frontResult = 0, backResult = 0;
int pointLoc = 0;
for(int i = 0; i < len; i++){
if(s[i] == '.'){
pointLoc = i;
break;
}
}
int index = 0;
if(pointLoc != 0){ //有小数点
while(index < pointLoc){
frontResult = frontResult * 10 + s[index++] - '0';
}
index++;
}
while(index < len){
backResult = backResult * 10 + s[index++] - '0';
}
return frontResult + backResult / 1000.0;
}
int main(){
int k = 0;
char mTime[20];
while(gets(nodeList[k].str)){
sscanf(nodeList[k].str, "%s%s%s%s", nodeList[k].name, nodeList[k].day, nodeList[k].time, mTime);
nodeList[k].mTime = CharArrayTodouble(mTime);
k++;
}
sort(nodeList, nodeList + k, CompareDesc);
for(int i = 0; i < k; i++){
cout << nodeList[i].str << endl;
}
return 0;
}
5、题目描述:给出两个不大于65535的非负整数,判断其中一个的16位二进制表示形式,是否能由另一个的16位二进制表示形式经过循环左移若干位而得到。 循环左移和普通左移的区别在于:最左边的那一位经过循环左移一位后就会被移到最右边去。比如: 1011 0000 0000 0001 经过循环左移一位后,变成 0110 0000 0000 0011, 若是循环左移2位,则变成 1100 0000 0000 0110【北京大学】
示例代码1(将两个字符串都先转换为二进制串,再进行比较):
#include
#include
#include
using namespace std;
const int STR_LENGTH = 16;
string DecimalToBinary(int n, int &oneNumer){
string result;
char c;
while(n != 0){
if(n % 2 == 1){
oneNumer++;
}
c = n % 2 + '0';
result = c + result;
n /= 2;
}
return result;
}
int main(){
int a, b, aOneCount, bOneCount;
string aStr, bStr;
while(cin >> a >> b){
aOneCount = bOneCount = 0;
aStr = DecimalToBinary(a, aOneCount);
bStr = DecimalToBinary(b, bOneCount);
while(aStr.size() < STR_LENGTH){
aStr = '0' + aStr;
}
while(bStr.size() < STR_LENGTH){
bStr = '0' + bStr;
}
if(bStr.size() < aStr.size()){
cout << "NO" << endl;
}else{
bool flag = false;
for(int i = 0; i < STR_LENGTH; i++){
aStr = aStr.substr(1) + aStr[0];
if(aStr == bStr){
flag = true;
break;
}
}
if(flag){
cout << "YES" << endl;
}else{
cout << "NO" << endl;
}
}
}
return 0;
}
示例代码2(利用位操作):
#include
using namespace std;
int main(){
unsigned short a, b;
while(cin >> a >> b){
bool flag = false;
for(int i = 0; i < 16; i++){
if(a == b){
flag = true;
break;;
}
a = a >> 1 | a << 15;
}
if(flag){
cout << "YES" << endl;
}else{
cout << "NO" << endl;
}
}
return 0;
}
附注:
(1)循环左移:如a = 01111011,循环左移两位,得11101101,分步实现为:b = a >> (8,2),右移六位,用来得到正常左移丢失的位,其正确位置,a = a << 2,左移两位,得到11101100,a = a | b
6、题目描述:先输入你要输入的字符串的个数。然后换行输入该组字符串。每个字符串以回车结束,每个字符串少于一百个字符。 如果在输入过程中输入的一个字符串为“stop”,也结束输入。 然后将这输入的该组字符串按每个字符串的长度,由小到大排序,按排序结果输出字符串。【北京大学】
示例代码:
#include
#include
#include
#include
using namespace std;
const int MAX_N = 101;
const int MAX_CASE = 500;
struct Node{
char a[MAX_N];
};
bool CompareAsc(const Node p1, const Node p2){
return strlen(p1.a) < strlen(p2.a);
}
int main(){
int n;
while(scanf("%d", &n) != EOF){
getchar();
Node *p = new Node[MAX_CASE];
int index;
for(index = 0; index < n; index++){
gets(p[index].a);
if(strcmp(p[index].a, "stop") == 0){
break;
}
}
sort(p, (p + index), CompareAsc);
for(int i = 0; i < index; i++){
printf("%s\n", p[i].a);
}
}
return 0;
}
7、题目描述:根据输入的运算符对输入的整数进行简单的整数运算。 运算符只会是加+、减-、乘*、除/、求余%、阶乘!六个运算符之一。 输出运算的结果,如果出现除数为零,则输出“error”,如果求余运算的第二个运算数为0,也输出“error”。【北京大学】
示例代码:
#include
using namespace std;
int main(){
char oper;
int a, b;
while(cin >> a >> oper){
if(oper == '!'){
long long result = 1;
for(int i = 1; i <= a; i++){
result *= i;
}
cout << result << endl;
}else{
cin >> b;
if(oper == '+'){
cout << a + b << endl;
}else if(oper == '-'){
cout << a - b << endl;
}else if(oper == '*'){
cout << a * b << endl;
}else if(b == 0){
cout << "error" << endl;
}else{
if(oper == '%'){
cout << a % b << endl;
}else if(oper == '/'){
cout << a / b << endl;
}
}
}
}
return 0;
}
8、题目描述:设计一个二次方程计算器【上海交通大学】
示例代码:
#include
#include
#include
#include
using namespace std;
struct Node{ //ax^2 + bx + c = 0;
int a;
int b;
int c;
Node(int a, int b, int c):a(a), b(b), c(c){};
};
int GetNumber(string s, int &index){
int result = 0;
while(s[index] >= '0' && s[index] <= '9'){
result = result * 10 + s[index] - '0';
index++;
}
return result;
}
int main(){
string s;
while(getline(cin ,s)){
Node node(0, 0, 0);
int i = 0, len = s.size(), param;
//operFlag判断是否为正负号,正号为true;equalFlag判断为等式的左右部分,左true
bool operFlag = true, equalFlag = true;
while(i < len){
param = 0;
if(s[i] == '='){
equalFlag = false;
operFlag = false; //右边部分默认操作符为减
}
if(s[i] == '-' || s[i] == '+'){
if((s[i] == '-' && equalFlag) || (s[i] == '+' && !equalFlag)){
operFlag = false;
}else{
operFlag = true;
}
}else if(s[i] >= '0' && s[i] <= '9'){
param = GetNumber(s, i);
if(!operFlag){
param *= -1;
}
}
if(i < len && s[i] == 'x'){
if(param == 0){
param = 1;
}
if(i + 1 < len && s[i + 1] == '^'){ //二次项系数
node.a += param;
i += 2;
}else{
node.b += param;
}
}else{
node.c += param;
}
i++;
}
int delta = node.b * node.b - 4 * node.a * node.c;
if(delta < 0){
cout << "No Solution" << endl;
}else if(delta == 0){
double result = -node.b / 2 / node.a;
cout << fixed << setprecision(2) << result << result << endl;
}else{
double sqrtValue = sqrt(delta);
double value1 = (-node.b - sqrtValue) / 2 / node.a;
double value2 = (-node.b + sqrtValue) / 2 / node.a;
if(value1 < value2){
cout << fixed << setprecision(2) << value1 << " " << value2 << endl;
}else{
cout << fixed << setprecision(2) << value2 << " " << value1 << endl;
}
}
}
return 0;
}
9、题目描述:有一个6*6的棋盘,每个棋盘上都有一个数值,现在有一个起始位置和终止位置,请找出一个从起始位置到终止位置代价最小的路径: 1、只能沿上下左右四个方向移动 2、总代价是每走一步的代价之和 3、每步(从a,b到c,d)的代价是c,d上的值与其在a,b上的状态的乘积 4、初始状态为1 每走一步,状态按如下公式变化:(走这步的代价%4)+1。【上海交通大学】
示例代码:
#include
#include
using namespace std;
const int MAX_N = 6;
const int MAX_INT = 0x7fffffff;
int matrix[MAX_N][MAX_N];//棋盘
int visit[MAX_N][MAX_N]; //结点是否已访问
int fromX, fromY, toX, toY;
int ans;
int direct[4][2] = {
{1, 0}, {0, 1}, {-1, 0}, {0, -1}
};
//price为到x,y结点的代价,status为上一步的状态,x、y为下一步要去的结点
void DFS(int x, int y, int status, int price){
if(x == toX && y == toY){
ans = min(ans, price);
return;
}
if(price >= ans){
return;
}
visit[x][y] = 1;
int newX, newY, newPrice, newStatus;//去下一步的代价,下一步的状态,下一步的x、y
for(int i = 0; i < 4; i++){
newX = x + direct[i][0];
newY = y + direct[i][1];
if(newX < MAX_N && newY < MAX_N && newX >= 0 && newY >= 0 && visit[newX][newY] == 0){
newPrice = status * matrix[newX][newY];
newStatus = (newPrice % 4) + 1;
DFS(newX, newY, newStatus, price + newPrice);
}
}
visit[x][y] = 0;
}
int main(){
while(cin >> matrix[0][0]){
for(int i = 1; i < MAX_N; i++){
cin >> matrix[0][i];
}
for(int i = 1; i < MAX_N; i++){
for(int j = 0; j < MAX_N; j++){
cin >> matrix[i][j];
}
}
cin >> fromX >> fromY >> toX >> toY;
memset(visit, 0, sizeof(visit));
//深度优先
ans = MAX_INT;
DFS(fromX, fromY, 1, 0);
cout << ans << endl;
}
return 0;
}
10、题目描述:一个N*M的矩阵,找出这个矩阵中所有元素的和不小于K的面积最小的子矩阵(矩阵中元素个数为矩阵面积)【上海交通大学】
示例代码:
#include
#include
using namespace std;
const int MAX_N = 101;
const int MAX_INT = 0x7fffffff;
int matrix[MAX_N][MAX_N];
int Short[MAX_N][MAX_N];//Short[i][j]表示从i到j的距离
int sum, result, resultRow;//sum用于求和整个数组所有元素,result为输出结果
int merge[MAX_N];
int n, m, k;
void GetShort(){
memset(Short, 0, sizeof(Short));
for(int i = 0; i < m; i++){
for(int j = i; j < m; j++){
if(j == i){
Short[i][j] = merge[i];
}else{
Short[i][j] = Short[i][j - 1] + merge[j];
}
if(Short[i][j] >= k){
if(resultRow * (j - i + 1) < result){
result = resultRow * (j - i + 1);
}
break;
}
}
}
}
int main(){
while(cin >> n >> m >> k){
sum = 0;
result = MAX_INT;
for(int i = 0; i < n; i++){
for(int j = 0; j < m; j++){
cin >> matrix[i][j];
sum += matrix[i][j];
}
}
if(sum < k){
cout << "-1" << endl;
}else{
for(int i = 0; i < n; i++){
for(int j = i; j < n; j++){//将第i行到第j行合并
if(j - i + 1 >= result){
break;
}else{
memset(merge, 0, sizeof(merge));
for(int p = 0; p < m; p++){
for(int k = i; k <= j; k++){
merge[p] += matrix[k][p];
}
}
resultRow = j - i + 1;
GetShort();
}
}
}
cout << result << endl;
}
}
return 0;
}
11、题目描述:存在两组数组,和4个数字a,b,c,d,要求做如下操作,将第一个数组第a个数到第b个数,第二个数组的第c个数到第d个数放到一个数组中,求出合并后数组的中间值,如果有两个中间值,取下标较小的那个。【上海交通大学】
示例代码:
#include
#include
#include
using namespace std;
vector a, b;
int main(){
int len1, len2;
int aFrom, aTo, bFrom, bTo;
int inputNum;
while(cin >> len1 >> len2){
a.clear();
b.clear();
for(int i = 0; i < len1; i++){
cin >> inputNum;
a.push_back(inputNum);
}
for(int i = 0; i < len2; i++){
cin >> inputNum;
b.push_back(inputNum);
}
cin >> aFrom >> aTo >> bFrom >> bTo;
int part1 = aTo - aFrom + 1;
int part2 = bTo - bFrom + 1;
int middle = (part1 + part2 - 1) / 2;
if(part1 > middle){
cout << a[aFrom + middle + 1] << endl;
}else{
cout << b[bFrom - 1 + middle - part1] << endl;
}
}
return 0;
}
12、题目描述:省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可)。经过调查评估,得到的统计表中列出了有可能建设公路的若干条道路的成本。现请你编写程序,计算出全省畅通需要的最低成本。【浙江大学】
示例代码:
#include
#include
#include
using namespace std;
//并查集 + 贪心
const int MAX_N = 101;
int father[MAX_N];
int height[MAX_N];
struct Node{
int from;
int to;
int price;
Node(int f, int t, int p):from(f), to(t), price(p){};
};
vector myList;
void Init(int m){
myList.clear();
for(int i = 1; i <= m; i++){
father[i] = i;
height[i] = 0;
}
}
int GetFather(int n){
while(n != father[n]){
n = father[n];
}
return father[n];
}
bool Union(int x, int y){
x = GetFather(x);
y = GetFather(y);
if(x != y){
if(height[x] < height[y]){
father[x] = y;
}else if(height[y] < height[x]){
father[y] = x;
}else{
father[x] = y;
height[y]++;
}
return false;
}
return true;
}
bool Compare(const Node &n1, const Node &n2){
return n1.price < n2.price;
}
int main(){
int n, m;//n条路,m个村
int from, to, price;
while(cin >> n >> m && n != 0){
Init(m);
for(int i = 0; i < n; i++){
cin >> from >> to >> price;
myList.push_back(Node(from, to, price));
}
sort(myList.begin(), myList.end(), Compare);
int result = 0, unionCount = 0;
for(int i = 0; i < myList.size(); i++){
if(!Union(myList[i].from, myList[i].to)){
result += myList[i].price;
}
}
for(int i = 1 ; i <= m; i++){
if(father[i] == i){
unionCount++;
}
}
if(unionCount == 1){
cout << result << endl;
}else{
cout << "?" << endl;
}
}
return 0;
}