题目22:约瑟夫环2
假设有k个人质和k个绑匪围成一圈。人质的编号从1到k,绑匪的编号从k+1到2k。从编号1开始,每次从其中选出第m个人(隔m-1选出一人)出列。希望求出m的最小值,使得最先出列的k个人都是绑匪,即都是编号从k+1到2k的人。
你写的程序要求从标准输入设备中读入测试数据作为你所写程序的输入数据。标准输入设备中有多组测试数据,每组测试数据仅一行,每组测试数据有一个整数k(1≤k≤10),表示人质的人数和绑匪的人数。每组测试数据与其后一组测试数据之间没有任何空行,第一组测试数据前面以及最后一组测试数据后面也都没有任何空行。
对于每一组测试数据,你写的程序要求计算出一组相应的运算结果,并将这一组运算结果作为你所写程序的输出数据依次写入到标准输出设备中。每组运算结果为一个整数m,即明明要选定的那个数。每组运算结果单独形成一行数据,其行首和行尾都没有任何空格,每组运算结果与其后一组运算结果之间没有任何空行,第一组运算结果前面以及最后一组运算结果后面也都没有任何空行。 注:通常,显示屏为标准输出设备。
总结:
1. 用数组alive记录每个人是否存活,1表示存活,索引0 – k-1对应人质(编号 1 – k),索引k – 2k-1对应绑匪(编号 k+1 – 2k)
2. pos指向当前位置,从当前起点开始,数 pos个存活的人,随后检查出局者是否为人质(索引 < k),若是人质则提前结束循环;若不为人质则将该位置标记出局,更新下一个起点
#include <stdio.h>
int check_m(int k, int m){
int n = 2 * k;
int alive[n]; //1表示存活
for(int i = 0; i < n; i++){
alive[i] = 1;
}
int current = 0; //第一次起点
for(int i = 0; i < k; i++){
int len = n – i; //当前剩余人数
int pos = (m – 1) % len; //要删除的人在当前环中的位置
int idx = current;
while(pos > 0){
idx = (idx + 1) % n;
if (alive[idx])
pos–;
}
//检查是否人质
if(idx < k){ //原始编号 0..k-1 是人质
return 0;
}
alive[idx] = 0;//删除这个人
int next_idx = idx;//找下一个起点
while(!alive[next_idx]){
next_idx = (next_idx + 1) % n;
}
current = next_idx;//下一轮起点
}
return 1;
}
int main() {
int k;
while(scanf("%d", &k) != EOF){
if(k == 0) break;
// m 至少为 k+1
for(int m = k + 1; ; m++)
if(check_m(k, m)){
printf("%d\\n", m);
break;
}
}
return 0;
}
题目29:求奇数的乘积
给你n个整数,求他们中所有奇数的乘积。
输入数据包含两行,第一行为一个数为n,表示第二行将输入n个整数。你可以假设这n个数据中必定至少存在一个奇数。输出一个整数。
总结:
使用for循环,奇数就相乘,偶数不做处理
#include <stdio.h>
int main(){
int n, sum = 1;
scanf("%d", &n);
for(int i = 0; i < n; i++){
int j;
scanf("%d", &j);
if(j % 2 == 1)
sum *= j;
}
printf("%d", sum);
return 0;
}
题目30:求最晚和最早日期
输入N个日期,每个以年、月、日的顺序读入,打印输出最晚的日期、最早的日期。
你的程序需要从标准输入设备(通常为键盘)中读入多组测试数据。每组输入数据由多行组成。每组测试数据的第一行输入一个整数N(0<N<20),表示有N个日期。其后N行每行有三个整数Y(1≤Y≤2015),M(1≤M≤12),D(1≤D≤31)表示一个日期。
对每组测试数据,你的程序需要向标准输出设备(通常为启动该程序的文本终端)输出两行,每行包括3个整数,第一行为最晚日期,第二行为最早日期,整数之间以一个空格分隔,行首与行尾无空格,所有数据前后没有多余的空行,两组数据之间也没有多余的空行。
总结:
对输入的年月日依次与当前最早最晚日期比较。先比较年份,若当前年份比最晚日期更大则更新,若年份相同则比较月份,月份相同则比较日期。
#include <stdio.h>
int main(){
int n, y, m, d;
int max_y = 0, max_m = 0, max_d = 0;
int min_y = 10000, min_m = 10000, min_d = 10000;
scanf("%d", &n);
for(int i = 0; i < n; i++){
scanf("%d%d%d", &y, &m, &d);
if(y > max_y || (y == max_y && m > max_m) || (y == max_y && m == max_m && d > max_d)){
max_y = y;
max_m = m;
max_d = d;
}
if(y < min_y || (y == min_y && m < min_m) || (y == min_y && m == min_m && d < min_d)){
min_y = y;
min_m = m;
min_d = d;
}
}
printf("%d %d %d\\n", max_y, max_m, max_d);
printf("%d %d %d", min_y, min_m, min_d);
return 0;
}


翻译:
随着智能体的学习,在某些情况下智能体的反应随着时间的推移而改进。这可以采取发展程序知识(学习“怎么样”)或者存储陈述性知识(学习“是什么”)的形式。学习程序知识经常涉及一个反复试验的过程,在这个过程中,智能体通过差的行动被惩罚和好的行动被奖励来学习合适的行动。按照这个方法,已经开发出了智能体,随着时间的推移,智能体在跳棋和国际象棋这种竞技性游戏上的能力提升了。学习陈述性知识经常采取扩大或者改变智能体知识库中的事实的形式。例如,棒球运动员必须通过对未来已经决定事件的合理反应来反复调整他/她知识的数据库。
为了对刺激产生合理的反应,智能体必须理解从传感器接收到的刺激。即智能体必须能从他传感器产生的数据中提取信息,或者换句话说,智能体必须能感知。在某些情况下这是一个直接的过程。从回转仪获得的信号很容易以与计算响应相兼容的形式进行编码。但是在其他情况下,从输入数据中提取信息很困难。例子包括理解语音和图像。同样地,就兼容它们的执行器而言,智能体必须能够制定它们的反应。这可能是一个直接的过程或者它需要智能体以完整的句子制定反应,意味着智能体必须生成语音。相反的,图像处理与分析,自然语言理解,生成语音等主题是研究的重要领域。
我们已经确认的智能体属性代表了过去和现在的研究领域。当然,它们彼此不是完全独立的。我们更想发展拥有全部属性的智能体,生产能够理解从它们所处环境接收到的数据的智能体,通过目标是最大化智能体能力的学习过程发展新的反应模式。然而,通过分离合理反应的各种类型,追求它们独立,研究者们获得了一个支点,这个支点后续可以与其他领域的进程连结起来去生产更多智能体。
