Reto Universidad [C++].

Iniciado por bigfu, 20 Julio 2011, 13:04 PM

0 Miembros y 1 Visitante están viendo este tema.

bigfu

Hola a todos, estoy estudiando este verano la asignatura de Fundamentos de la Programación para presentarme en septiembre, y se me ocurrió la idea de plantear aqui los ejercicios de cada tema (cada cierto tiempo) y asi poder comparar mis soluciones con las vuestras (no estoy pidiendo que me hagais los ejercicios), para ver si hubiese podido simplificar más el código y aprender un poco de vosotros; a la par de que al ser ejercicios de una asignatura de fundamentos, va a venir muy bien para todos aquellos que quieran aprender/estén aprendiendo C++.
La dificultad de los ejercicios se irá incrementando conforme vaya avanzando en los temas (espero que un tema cada dos días como mucho xD), y diré con cada ristra de ejercicios que está y que no está permitido utilizar, ya que puede ser anterior al tema donde se dan los vectores o recursividad, por poner un ejemplo. Si alguien está interesado, podría pasarle por privado los pdf's de cada tema o del tema en concreto.

CitarTema 1
En este tema se hace una introducción a C++, se ven los tipos de datos simples, las constantes, variables y asignaciones, la entrada y salida básicas, el flujo de control, las expresiones lógicas o booleanas y las estructuras de selección (if y switch) e iteración (while, do-while, for). También se hace mención al control de errores y excepciones, pero no pone mucho interés en ello, se puede obviar xD

Ejercicios Tema 1
1.- Confecciona un bucle que lea de teclado un texto carácter a carácter hasta localizar un punto, y que al final dé como salida el número de comas encontradas, y el número de caracteres leídos.

2.- Diseña un algoritmo que determine si la cadena 'abc' aparece en una sucesión de caracteres cuyo final viene dado por un punto.

3.- Diseña un algoritmo que lea un número n por teclado y calcule el n-ésimo número de la serie de Fibonacci. Los dos primeros números de esta serie son el cero y el uno, y a partir de éstos cada número se calcula realizando la suma de los dos anteriores.

4.- Escribe un algoritmo que encuentre el mayor, el menor y la media aritmética de una colección de N números leídos por el teclado donde N es el primero de los números.

5.- Escribe un algoritmo que lea una lista de números enteros terminada en 0, y que encuentre y escriba en la pantalla la posición de la primera y de la última ocurrencia del número 12 dentro de la lista. Si el número 12 no está en la lista, el algoritmo debería escribir 0. Por ejemplo, si el octavo número de la lista es el único 12, entonces 8 sería la primera y la última posición de las ocurrencias de 12.

6.- Desarrolla un algoritmo para el siguiente juego:
El usuario introduce un límite inferior, un límite superior y piensa un número en ese rango. El ordenador tiene que acertarlo. Para ello el ordenador propone un número y el usuario responde con >, < o = (correspondiente a acertado y el programa acaba). Si la respuesta es > o <, el ordenador propondrá otro número hasta que lo acierte.
(Si mal no recuerdo, para este ejercicio, el profesor indicó que tanto el usuario como el ordenador, somos nosotros, sino sería más complicado hacerlo con lo visto hasta ahora XD)

7.- Desarrollar un algoritmo para el siguiente juego:
El usuario introduce un número natural n que representa a n objetos. La máquina decide quien empieza y alternativamente, el usuario y la máquina retiran cada uno 1, 2 o 3 objetos (es decir, elige restar 1, 2 o 3 a n). El que retira el último objeto pierde.
En las condiciones del problema, es posible desarrollar un algoritmo para que siempre gane la máquina. Construir tal algoritmo.

CitarTema 2
En este tema se ve el diseño descendente, procedimientos y funciones (definición y declaración, llamada, parámetros reales y formales, paso de parámetros por valor y por referencia, interfaz, criterios de modularización, variables locales y globales y precondiciones y postcondiciones) y recursividad.
Lo mismo que en el tema anterior, si hay alguien interesado en el pdf, que lo pida y se lo paso.

Ejercicios Tema 2
1.- Escribe un programa que lea un número natural N por teclado y dibuje un triángulo de asteriscos con base y altura N. Por ejemplo, si N=5 debería dibujar:
    *
   * *
  * * *
 * * * *
* * * * *

2.- Escribe un programa que tome como entrada desde teclado dos números naturales (mayores que cero) "N" e "i", e imprima en pantalla el dígito que ocupa la posición i-ésima del número N. Si i es mayor que el número de dígitos de N, se escribirá en pantalla -1. Por ejemplo, para N=25064 e i=2, el resultado es el dígito 6, y para i=7, el resultado es -1.

3.- Escribe un programa que acepte como entrada desde teclado un número natural mayor que cero y dé como salida el resultado de sumar dos a dos los dígitos que aparecen en posiciones simétricas respecto al dígito central dentro del número dado como entrada. Por ejemplo:
para el número: 2354869
la salida es: 2+9=11, 3+6=9, 5+8=13, 4
para el número: 6582
la salida es: 6+2=8, 8+5=13

4.- Dada una sucesión, de longitud indeterminada, de ceros y unos, construir un programa que permita calcular el tamaño de la mayor sucesión ordenada de menor a mayor. La sucesión se lee desde teclado, y el final viene dado por el número 2.

5.- Decimos que una sucesión a1,a2,...,an de enteros forma una montaña, si existe un h tal que: 1 <= h <= n y además a1<...ah-1 < ah > ah+1 > ...an
Por ejemplo 24, 13, 6, 15, 50 sería un valle.
Dada una secuencia de enteros terminada en cero (0) que como mínimo contiene una montaña y un valle (suponemos que la secuencia de enteros de entrada es una secuencia correcta de montañas y valles), diseña un programa que calcule la longitud de la montaña y el valle más largos.

6.- El máximo común divisor (mcd) de dos números naturales p y q es el mayor entero d que divide a ambos. Un algoritmo muy conocido para calcularlo es el de Euclides. Éste utiliza dos variables, que contienen inicialmente a cada uno de los números, y trata de hacer que su contenido sea el mismo. Para ello, irá restando la menor a la mayor hasta que ambas contengan el mismo valor. En dicho momento, el valor obtenido en cualquiera de ellas es el máximo común divisor de los dos números iniciales. Por ejemplo, si P=18 y Q=12, el algoritmo hará que P y Q vayan tomando los siguientes valores:
Inicialmente P==18 y   Q==12     (P>Q => P=P-Q)
Después      P==6   y   Q==12     (Q>P => Q=Q-P)
Después      P==6   y   Q==6       (P==Q => El mcd es 6)

Diseña el algoritmo anterior siguiendo un enfoque recursivo:
unsigned mcd(unsigned P, unsigned Q)

7.- Diseña un procedimiento recursivo que lea una secuencia de caracteres de longitud arbitraria terminada en un punto, y la imprima en orden inverso. El procedimiento no tiene parámetros.

CitarTema 3
En este tema se ven los tipos de datos estructurados: Registros, arrays y cadenas de caracteres (tipo string) y la resolución de problemas usando tipos estructurados.
ESTE TEMA ES EL ÚLTIMO DE LA ASIGNATURA.

Ejercicios Tema 3
1.- Diseña un algoritmo que permita invertir el contenido de un array. El algoritmo no podrá utilizar arrays auxiliares. Impleméntalo de forma iterativa y recursiva.
Array Original: 24 12 45 90 7 9 15
Array Invertido: 15 9 7 90 45 12 24

2.- Escriba un programa que efectúe la conversión de un número natural en base 10 a otra determinada base, sabiendo que el resultado no sobrepasará los 50 dígitos. El usuario introducirá primero el número en base 10 y después la base a la que convertirlo (el programa debe asegurarse de que la base no sea ni menor de 2 ni mayor de 9)

3.- Diseña un algoritmo que lea un texto de longitud indefinida formado por letras mayúsculas (que termina con un punto) y muestre por pantalla la frecuencia con la que aparece cada una de las letras del texto.

4.- Dados los siguientes tipos (para una constante MAX cualquiera):
Código (cpp) [Seleccionar]
typedef char Componentes[MAX]
struct Vector{
   Componentes datos;   //array de caracteres
   unsigned tam             //numero de celdas ocupadas
};

a) La moda de un array de caracteres es el carácter del array que se repite más frecuentemente. Si varios caracteres se repiten con la misma frecuencia máxima, entonces no hay moda. Escribe un procedimiento con tres parámetros. El primero es de entrada para recibir un registro de tipo Vector que contiene el array datos con tam caracteres. El segundo parámetro es de salida e indicará si se ha encontrado la moda en el array o no. El tercer parámetro es de salida y será el carácter que representa la moda (si es que existe).
b) Diseña una función booleana que dados dos registros de tipo Vector como parámetros devuelva TRUE si son iguales y FALSE en otro caso. Dos vectores son iguales si contienen los mismos elementos y en el mismo orden relativo, suponiendo que el primer elemento sigue al último. Por ejemplo, si los arrays fueran:
['A', 'C', 'D', 'F', 'E']
['D', F', 'E', 'A', 'C']
la función devolvería TRUE.
Supón, además, que cada carácter aparece a lo sumo una vez.
c) Diseña un procedimiento que tome como parámetros de entrada dos vectores con los arrays ordenados y devuelva (con un perámetro de salida) el vector resultado de realizar la mezcla ordenada de los dos arrays contenidos en los vectores de entrada.

5.- Los alumnos de informática desean celebrar una comida un día del presente mes en el que puedan acudir todos. Se pide realizar un algoritmo que recoja de cada alumno los días que le vendría bien ir a la comida, e imprima las fechas concordantes para todos los alumnos. Los datos se introducirán por teclado, y cada alumno escribirá una única línea con los números de los días libres separados por espacios.

6.- Se tiene un array de enteros. Obtén otro de forma que el contenido de cada elemento del nuevo array sea un índice que nos indique de menor a mayor los valores del array de enteros. El array original no se podrá modificar, ni se puede hacer copia del mismo. Por ejemplo:
[10,5,-7,0,12] ---> [2,3,1,0,4]

7.- La distancia entre dos letras en un texto es el número de letras que aparecen en el texto entre las dos letras indicadas. Diseñe un algoritmo que lea un texto de longitud indefinida formado por letras mayúsculas (que termina con un punto) y muestre por pantalla la máxima distancia entre cada par de letras repetidas. Aquellas letras que no se repitan no aparecerán en la salida.
Por ejemplo:
- Texto de entrada: ABEADDGLAKE.
- Salida:
    · Distancia entre A: 4
    · Distancia entre D: 0
    · Distancia entre E: 7

8.- Diseña un algoritmo para calcular la suma de los elementos de la diagonal principal de una matriz cuadrada.

9.- Una matriz tiene un punto silla en una de sus componentes, si ese componente es el mayor valor de su columna y el menor de su fila. Diseña un algoritmo que recogiendo de teclado los componentes de una matriz cuadrada de enteros de hasta un máximo de 10x10, muestre en la pantalla las coordenadas de todos sus puntos silla.

10.- Diseñe un algoritmo que lea de teclado un texto y muestre un listado por pantalla de todas las palabras del texto que comiencen por ciertas iniciales. Dichas iniciales serán las letras que formen la primera palabra del texto.
NOTAS:
- El texto contiene un número indefinido de palabras.
- El texto termina con la palabra FIN
- Cada palabra tiene un número indefinido pero limitado de caracteres (todos alfabéticos mayúsculas)
- El carácter separador de palabras es el espacio en blanco.

11.- Diseñe un algoritmo que lea de teclado un patrón (una cadena de caracteres) y un texto, y dé como resultado las palabras del texto que contenga a dicho patrón. En la salida no habrá palabras repetidas. Ejemplo:
·Patrón: RE
·Texto: CREO QUE IREMOS A LA DIRECCION QUE NOS DIERON AUNQUE PIENSO QUE DICHA DIRECCION NO ES CORRECTA FIN
·Salida: CREO IREMOS DIRECCION CORRECTA

NOTAS:
- El texto contiene un número indefinido de palabras.
- El texto termina con la palabra FIN.
- Cada palabra tiene un número indefinido pero limitado de caracteres (todos alfabéticos mayúsculas).
- El caracter separador de palabras es el espacio en blanco.
- En el texto aparecerán un número máximo MAX_PAL_DIST (una constante) de palabras distintas.

12.- Una farmacia desea almacenar sus productos (TProducto) en una estructura. De cada producto hay que almacenar la siguiente información: código (unsigned), nombre (string), precio (float), fecha de caducidad (definir un tipo registro para la fecha). Diseña la estructura de datos (TFarmacia) para almacenar un máximo de MAX (una constante) productos y realiza los siguientes subalgoritmos:
- void LeerProducto(TProducto& p)
- void EscribirProducto(const TProducto& p)
- void InicializarFarmacia(TFarmacia& f)
 void InsertarProducto(TFarmacia& f, const TProducto& p)
- void BorrarProducto(TFarmacia& f, unsigned codigo)
- void BuscarProductoCodigo(const TFarmacia& f, unsigned codigo, bool&   encontrado, TProducto& p)
- void ListarFarmacia(const TFarmacia& f)
A reader lives a thousand lives before he dies. The man who never reads lives only one

bigfu

#1
EDIT: Pongo aqui las soluciones y asi "despejo" un poco el primer post.

CitarSoluciones Tema 1
Ejercicio 1
Código (cpp) [Seleccionar]
#include <iostream>
using namespace std;

int main() {
char c;
int comas, numChar;

numChar = 0;
comas = 0;

cout << "Introduzca texto terminado en '.': ";
do{
cin.get(c);
numChar++;
if(c==','){
comas++;
}
}while(c!='.');

cout << "Numero de comas: " << comas << endl;
cout << "Numero de caracteres: " << numChar << endl;
return 0;
}


Ejercicio 2
Código (cpp) [Seleccionar]
#include <iostream>
using namespace std;

int main() {
bool enc = false;
char c;

cout << "Introduzca una sucesion de caracteres terminada en '.': ";
cin >> c;
do{
if(c=='a'){
cin>>c;
if(c=='b'){
cin>>c;
if(c=='c'){
enc=true;
cin>>c;
}
}
}else{
cin>>c;
}
}while(c!='.');

if(enc){
cout << "La cadena 'abc' se encuentra en la sucesión de caracteres.";
}else{
cout << "La cadena 'abc' no se encuentra en la sucesión de caracteres.";
}
return 0;
}


Ejercicio 3
Código (cpp) [Seleccionar]
#include <iostream>
using namespace std;

int main() {
unsigned n, fib, temp1, temp2;

fib = 0;
temp1 = 0;
temp2 = 1;
cout << "Introduzca un numero: ";
cin >> n;
cout << fib << "," << temp2;
for(unsigned i=2;i<n;i++){
fib = temp1+temp2;
temp1 = temp2;
temp2 = fib;
cout << "," << fib;
}
cout << "." << endl;
return 0;
}


Ejercicio 4
Código (cpp) [Seleccionar]
#include <iostream>
using namespace std;

int main() {
unsigned may,men,n,num;
float media;
cout << "Introduzca lista de numeros: ";
cin >> n;
may = n;
men = n;
media = n;
for(unsigned i=1;i<n;i++){
cin>>num;
if(num>may){
may=num;
}else if(num<men){
men=num;
}
media = media + num;
}
cout << "El mayor es: " << may << endl;
cout << "El menor es: " << men << endl;
cout << "La media aritmetica es: " << media/n << endl;
return 0;
}


Ejercicio 5
Código (cpp) [Seleccionar]
#include <iostream>
using namespace std;

int main() {
int num, prim, ult, pos;

pos = 1;
prim = 0;
ult = 0;
cout << "Introduzca una lista de numeros terminada en 0: ";
do{
cin >> num;
if((num==12)&&(prim==0)){
prim = pos;
ult = pos;
}else if((num==12)&&(prim!=0)){
ult = pos;
}
++pos;
}while(num!=0);

if((prim==0)&&(ult==0)){
cout << "Posicion 0" << endl;
}else{
cout << "Primera posicion: " << prim << endl;
cout << "Ultima posicion: " << ult << endl;
}
return 0;
}


Ejercicio 6
Código (cpp) [Seleccionar]
#include <iostream>
#include <cstdlib>
using namespace std;

int main() {
int inf, sup, num;
char c;

cout << "Introduzca rango inferior: ";
cin >> inf;
cout << "Introduzca rango superior: ";
cin >> sup;
cout << "Piense un numero en ese rango." << endl;
do{
do{
num = rand() % (sup-inf+1)+inf;  //Rango del numero aleatorio entre inf y sup
}while((num<inf)||(num>sup));
cout << "Es " << num << " el numero pensado?";
do{
cin >> c;
}while((c!='<')&&(c!='>')&&(c!='='));
cout << endl;
switch(c){
  case '<': sup = num-1;
    break;
  case '>': inf = num+1;
    break;
  case '=': cout << "Lo encontre!!" << endl;
    break;
}
}while(c!='=');
return 0;
}

NOTA: Me ha parecido más interesante utilizar la función rand() y hacerlo más acorde al enunciado del ejercicio. Se admiten sugerencias de mejora xD

Ejercicio 7
Código (cpp) [Seleccionar]
#include <iostream>
using namespace std;

int main() {
unsigned n, mod, resta;
bool sacar = true;

do{
cout << "Introduzca numero de objetos: ";
cin >> n;
}while(n<=0);
if(n%4==1){
sacar = false;
}
do{
if(!sacar){
cout << "Sacar 1, 2 o 3 objetos? ";
do{
cin >> resta;
}while((resta<1)||(resta>3)||(resta>n));
n-=resta;
cout << "Quedan " << n << " objetos." << endl;
sacar = true;
}else{
mod = n%4;
switch(mod){
case 0: cout << "La maquina resta 3. ";
n-=3;
cout << "Quedan " << n << " objetos" << endl;
sacar = false;
break;
case 3: cout << "La maquina resta 2. " << endl;
n-=2;
cout << "Quedan " << n << " objetos" << endl;
sacar = false;
break;
case 2: cout << "La maquina resta 1. " << endl;
n-=1;
cout << "Quedan " << n << " objetos" << endl;
sacar = false;
break;
}
}
}while(n!=0);
cout << "LO SIENTO, HAS PERDIDO. LA MAQUINA GANA!!" << endl;

return 0;
}

CitarSoluciones Tema 2
Ejercicio 1
Código (cpp) [Seleccionar]
#include <iostream>
using namespace std;

void introDatos(unsigned& num);
void pintaTriangulo(unsigned num);

int main(){
unsigned num;

introDatos(num);
pintaTriangulo(num);

return 0;
}

void introDatos(unsigned& num){
cout << "Introduzca numero N: ";
do{
cin >> num;
}while(num<=0);
}

void pintaTriangulo(unsigned num){
unsigned aux = (num-1);

for(unsigned i=0;i<num;i++){
for(unsigned j=0;j<num*2-1;j++){
if((i+j>=num-1)&&(i+j<=aux)){
if(num%2!=0){
if((j+i)%2==0){
cout << '*';
}else{
cout << " ";
}
}else{
if((j+i)%2!=0){
cout << '*';
}else{
cout << " ";
}
}
}else{
cout << " ";
}
}
aux+=2;
cout << endl;
}
}


Ejercicio 2
Código (cpp) [Seleccionar]
#include <iostream>
using namespace std;

void introDatos(unsigned& n, unsigned& i);
unsigned numDig(unsigned n);
void imprimirDig(unsigned n, unsigned i);

int main() {
unsigned n, i, num;

introDatos(n,i);
num = numDig(n);
if(num<i){
cout << -1 << endl;
}else{
imprimirDig(n,i);
}
return 0;
}

void introDatos(unsigned& n, unsigned& i){
do{
cout << "Introduzca numero N: ";
cin >> n;
}while(n<=0);
do{
cout << "Introduzca posicion: ";
cin >> i;
}while(i<=0);
}

unsigned numDig(unsigned n){
unsigned cont = 0;
while(n!=0){
n = n/10;
cont++;
}
return cont;
}

void imprimirDig(unsigned n, unsigned i){
unsigned j=0, dig;

while(j<i){
dig = n%10;
j++;
n = n/10;
}
cout << dig << endl;
}


Ejercicio 3
Código (cpp) [Seleccionar]
#include <iostream>
using namespace std;

void introducirDatos(unsigned& n);
unsigned longNum(unsigned n);
void imprimirSuma(unsigned n, unsigned longitud);
void Suma2a2(unsigned n, unsigned longitud);
unsigned potencia(unsigned longitud);

int main() {
unsigned n, longitud;

introducirDatos(n);
longitud = longNum(n);
imprimirSuma(n,longitud);

return 0;
}

void introducirDatos(unsigned& n){
cout << "Introducir numero N: ";
do{
cin >> n;
}while(n<=0);
}

unsigned longNum(unsigned n){
unsigned cont = 0;
while(n!=0){
n = n/10;
cont++;
}
return cont;
}

void imprimirSuma(unsigned n, unsigned longitud){
unsigned pot = potencia(longitud/2 + 1);

cout << "Para el numero: " << n << endl;
if(longitud%2!=0){
Suma2a2(n,longitud);
n = n/pot;
cout << ", " << n%10 << endl;
}else{
Suma2a2(n,longitud);
}
}

void Suma2a2(unsigned n, unsigned longitud){
unsigned j=10, suma, i;

i = potencia(longitud);
cout << "la salida es: ";
while(i>=j){
suma = 0;
suma = ((n/i) + (n%j));
cout << n/i << " + " << n%j << " = " << suma;
n%=i;
n/=10;
i/=100;
if(i>=j){
cout << ", ";
}
}
}

unsigned potencia(unsigned longitud){
unsigned pot = 1;
for(unsigned i=0;i<longitud;i++){
pot*=10;
}
return pot/10;
}


Ejercicio 4
Código (cpp) [Seleccionar]
#include <iostream>
using namespace std;

unsigned subsucesiones();

int main() {
unsigned mayor = subsucesiones();

cout << "La subsucesion mas larga es de tamaño " << mayor << endl;
return 0;
}

unsigned subsucesiones(){
unsigned aux = 0, cont = 0, suma = 0, n;

do{
do{
cin >> n;
if(n==2){
break;
}
}while((n!=0)&&(n!=1));
if(aux==n){
cont++;
if(cont>suma){
suma = cont;
}
}else if((n>aux)&&(n!=2)){
cont++;
if(cont>suma){
suma = cont;
}
aux = n;
}else if(aux>n){
cont = 1;
aux = 0;
}
}while(n!=2);
return suma;
}


Ejercicio 5
Código (cpp) [Seleccionar]
#include <iostream>
using namespace std;

void paisaje(int num, int& ant, unsigned& a, unsigned&b, bool& subida, bool& p_bajo);

int main() {
int num, ant=0;
bool subida_m = false, p_bajo = false;
unsigned m = 0, v = 0;
unsigned a = 0, b = 0;

cout << "Introduzca secuencia de enteros: ";
do{
cin >> num;
paisaje(num,ant,a,b,subida_m,p_bajo);
if(a>m){
m = a;
}
if(b>v){
v = b;
}
}while(num!=0);

cout << "La montaña mas larga: " << m << endl;
cout << "El valle mas largo: " << v << endl;

return 0;
}

void paisaje(int num, int& ant, unsigned& a, unsigned& b, bool& subida, bool& p_bajo){
if(ant==0){
ant = num;
a++;
b++;
}else if((num<ant)&&(num!=0)&&(!p_bajo)){
ant = num;
a++;
b++;
}else if((num<ant)&&(num!=0)&&(p_bajo)){
p_bajo = false;
b = 2;
a++;
ant = num;
}else if((num>ant)&&(!subida)&&(num!=0)&&(!p_bajo)){
a = 2;
b++;
ant = num;
subida = true;
p_bajo = true;
}else if((num>ant)&&(subida)&&(num!=0)&&(p_bajo)){
a++;
b++;
ant = num;
}
}


Ejercicio 6
Código (cpp) [Seleccionar]
#include <iostream>
using namespace std;

unsigned mcd(unsigned P, unsigned Q);

int main() {
unsigned p,q,resultado;

cout << "Introduzca P: ";
cin >> p;
cout << "Introduzca Q: ";
cin >> q;
resultado = mcd(p,q);
cout << "El mcd de " << p << " y " << q << " es: " << resultado << endl;

return 0;
}

unsigned mcd(unsigned P, unsigned Q){
unsigned res=0;

if(P==Q){
res = P;
}else if(P>Q){
res = mcd(P-Q,Q);
}else if(P<Q){
res = mcd(P,Q-P);
}

return res;
}


Ejercicio 7
Código (cpp) [Seleccionar]
#include <iostream>
using namespace std;

void inv_sec();

int main() {
cout << "Introduzca caracteres terminados en punto: ";
inv_sec();
return 0;
}

void inv_sec(){
char c;

cin.get(c);
if(c=='.'){

}else{
inv_sec();
cout << c;
}
}


CitarSoluciones Tema 3
Ejercicio 1
Código (cpp) [Seleccionar]
#include <iostream>
using namespace std;

const unsigned MAX = 10;

typedef unsigned TArray[MAX];

void introDatos(TArray& a);
void intercambiar(TArray& a);
void pintaArray(const TArray& a);

int main() {
TArray a;

introDatos(a);
pintaArray(a);
intercambiar(a);
pintaArray(a);

return 0;
}

void introDatos(TArray& a){
cout << "Introduzca datos: ";
for(unsigned i=0;i<MAX;i++){
cin >> a[i];
}
}

void intercambiar(TArray& a){
unsigned i=0;
unsigned j=MAX-1;
unsigned aux;


while(i<=j){
aux = a[i];
a[i] = a[j];
a[j] = aux;
i++;
j--;
}
}

void pintaArray(const TArray& a){
for(unsigned i=0;i<MAX;i++){
cout << a[i] << " ";
}
cout << endl;
}


Ejercicio 2
Código (cpp) [Seleccionar]
#include <iostream>
using namespace std;

const unsigned MAX = 50;
typedef unsigned TArray[MAX];

void conversion(TArray& a, unsigned num, unsigned base, unsigned& pos);
void intercambiar(TArray& a, unsigned pos);
void pintaMatriz(const TArray& a, unsigned pos);

int main() {
TArray a = {0};
unsigned num, base, pos;

cout << "Introduzca numero en base 10: ";
cin >> num;
cout << "Introduzca base para la conversion: ";
do{
cin >> base;
}while((base<2)||(base>9));
conversion(a,num,base,pos);
intercambiar(a,pos);
cout << "El numero " << num << " en base " << base << " es: ";
pintaMatriz(a,pos);

return 0;
}

void conversion(TArray& a, unsigned num, unsigned base, unsigned& pos){
pos = 0;

do{
a[pos] = num%base;
num/=base;
pos++;
}while(num>0);
}

void intercambiar(TArray& a, unsigned pos){
unsigned i=0, j=pos-1;
unsigned aux;

while(i<=j){
aux = a[i];
a[i] = a[j];
a[j] = aux;
i++;
j--;
}
}

void pintaMatriz(const TArray& a, unsigned pos){
for(unsigned i=0;i<pos;i++){
cout << a[i];
}
}


Ejercicio 3
Código (cpp) [Seleccionar]
#include <iostream>
#include <string>
using namespace std;

const unsigned MAX_ARRAY = 26;
typedef unsigned TArray[MAX_ARRAY];

void leerTexto(string& s);
void cuentaPalabras(const string& s, TArray& a);
void pintaMatriz(const TArray& a);

int main() {
TArray a = {0};
string s;

leerTexto(s);
cuentaPalabras(s,a);
pintaMatriz(a);

return 0;
}

void leerTexto(string& s){
char c;

cout << "Introduzca texto acabado en '.': ";
do{
cin >> c;
if(((c>='A')&&(c<='Z')||(c=='.'))){
s+=c;
}
}while(c!='.');
}

void cuentaPalabras(const string& s, TArray& a){
for(unsigned i=0;i<s.size()-1;i++){
a[int(s[i]-int('A'))]++;
}
}

void pintaMatriz(const TArray& a){
char c;
for(unsigned i=0;i<MAX_ARRAY;i++){
c = char((i+int('A')));
cout << c << ": " << a[i] << endl;
}
}


Ejercicio 4
Código (cpp) [Seleccionar]
typedef char Componentes[MAX]
struct Vector{
   Componentes datos;
   unsigned tam;
};
const unsigned TAMANYO = 128;
typedef unsigned TArray[TAMANYO];

a)
Código (cpp) [Seleccionar]
void moda(const Vector& v, bool& enc, char& c){
   TArray a = {0};
   for(unsigned i=0;i<v.tam;i++){
      a[int(v.datos)]++;
   }
   unsigned cantidad = a[0];
   enc = true;
   c = char(0);
   for(unsigned j=1;j<TAMANYO;j++){
      if(a[j]>cantidad){
         enc = true;
         c = char(j);
         cantidad = a[j];
      }else if(a[j] = cantidad){
         enc = false;
      }
   }
}

b)
Código (cpp) [Seleccionar]
bool iguales(const Vector& a, const Vector& b){
   int ind = indice(a,b);
   unsigned i = 1, j = ind + 1;
   bool igual = false;

   if(ind < 0){
      return false;
   }else{
      while(i<a.tam){
         if((a.datos[i] == b.datos[j]) && (j<b.tam)){
            igual = true;
            i++;
            j++;
         }else if(j>=b.tam){
            j=0;
         }else if(a.datos[i]!=b.datos[j]){
            igual = false;
            break;
         }
      }
      return igual;
   }
}

int indice(const Vector& a, const Vector& b){
   bool enc = false;
   unsigned i=0;

   if(a.tam != b.tam){
      return -1;
   }else{
      while((!enc) || (i<b.tam)){
         if(a.datos[0] == b.datos[i]){
            return i;
            enc = true;
         }else{
            i++;
         }
      }
      if(!enc){
         return -1;
      }
   }
}

c)
Código (cpp) [Seleccionar]
void ordena(const Vector& a, const Vector& b, Vector& c){
/*Suponemos c inicializados correctamente*/
   unsigned i=j=0, k=0;

   while((i<a.tam)&&(j<b.tam)){
      if(a.datos[i]<b.datos[j]){
         c[k] = a.datos[i];
         k++;
         i++;
      }else if(a.datos[i] > b.datos[j]){
         c[k] = b.datos[j];
         k++;
         j++;
      }else if(a.datos[i] == b.datos[j]){
         c[k] = a.datos[i];
         k++;
         i++;
         c[k] = b.datos[j];
         k++;
         j++;
      }
   }
   if(i==a.tam){
      for(unsigned m=j;m<b.tam;m++){
         c[k] = b.datos[m];
         k++;
   }else if(j == b.tam){
      for(unsigned n=i;n<a.tam;n++){
         c[k] = a.datos[n];
         k++;
      }
   }
}


Ejercicio 5
Código (cpp) [Seleccionar]
#include <iostream>
using namespace std;

const unsigned DIAS = 31;
typedef bool TFechas[DIAS];

void inicializar(TFechas& f);
void introFechas(TFechas& f);
void comparar(TFechas& f, const TFechas& g);
void pintaFechas(const TFechas& f);

int main() {
unsigned i=1;
TFechas a, fechas;

inicializar(fechas);
introFechas(fechas);
do{
inicializar(a);
introFechas(a);
comparar(fechas,a);
i++;
}while(i<25);

cout << "Las días compatibles son: ";
pintaFechas(fechas);

return 0;
}

void inicializar(TFechas& f){
for(unsigned i=0;i<DIAS;i++){
f[i] = false;
}
}

void introFechas(TFechas& f){
unsigned dias;
cout << "Introduzca los dias que puede ir: ";
do{
cin >> dias;
if((dias>=1)&&(dias<=31)){
f[dias-1] = true;
}
}while(dias>0);
}

void comparar(TFechas& f, const TFechas& g){
for(unsigned i=0;i<DIAS;i++){
if((f[i]==true)&&(g[i]==false)){
f[i]=false;
}
}
}

void pintaFechas(const TFechas& f){
for(unsigned i=0;i<DIAS;i++){
if(f[i]==true){
cout << i+1 << " ";
}
}
}


Ejercicio 6
Código (cpp) [Seleccionar]
#include <iostream>
using namespace std;

const unsigned MAX = 5;
typedef int TArray[MAX];

void introDatos(TArray& a);
int mayor(const TArray& a);
int menor(const TArray& a);
void introPos(const TArray& a, TArray& b, unsigned& i, int n, unsigned& j);
int generarSigNum(const TArray& a, int sup, int inf);
void pintaArray(const TArray& b);

int main() {
TArray a,b;
unsigned i = MAX-1,j=0;
int sup, inf;

introDatos(a);
sup = mayor(a);
inf = menor(a);
while(j<=MAX){
introPos(a,b,i,sup,j);
sup = generarSigNum(a,sup,inf);
}
pintaArray(b);

return 0;
}

void introDatos(TArray& a){
cout << "Introduzca numero naturales: ";
for(unsigned i=0;i<MAX;i++){
cin >> a[i];
}
}

int mayor(const TArray& a){
int m = a[0];

for(unsigned i=1;i<MAX;i++){
if(a[i]>m){
m = a[i];
}
}
return m;
}

int menor(const TArray& a){
int m = a[0];

for(unsigned i=0;i<MAX;i++){
if(a[i]<m){
m = a[i];
}
}
return m;
}

void introPos(const TArray& a, TArray& b, unsigned& i,int n, unsigned& j){
for(unsigned k=0;k<MAX;k++){
if(a[k]==n){
b[i]=k;
i--;
j++;
}
}
}

int generarSigNum(const TArray& a, int sup, int inf){
for(unsigned i=0;i<MAX;i++){
if((a[i]>=inf)&&(a[i]<sup)){
inf = a[i];
}
}
return inf;
}

void pintaArray(const TArray& b){
for(unsigned i=0;i<MAX;i++){
cout << b[i] << " ";
}
}


Ejercicio 7
Código (cpp) [Seleccionar]
#include <iostream>
#include <string>
using namespace std;

const unsigned MAX = 26;
typedef unsigned TLetras[MAX];
typedef bool TArray[MAX];

void introTexto(string& txt);
void contarLetras(const string& txt, TLetras& l, TArray& a);
void pintaLetras(const TLetras& l, const TArray& a);

int main() {
TLetras l = {0};
TArray a = {false};
string t;

introTexto(t);
contarLetras(t,l,a);
pintaLetras(l,a);

return 0;
}

void introTexto(string& txt){
char c;

cout << "Introduzca texto terminado en '.': ";
do{
cin >> c;
if((c>='A')&&(c<='Z')){
txt+=c;
}
}while(c!='.');
txt+='.';
}

void contarLetras(const string& txt, TLetras& l, TArray& a){
unsigned cont;

for(unsigned i=0;i<txt.size()-1;i++){
cont = 0;
for(unsigned j=i+1;j<txt.size()-1;j++){
if(txt[i]==txt[j]){
a[int(txt[i])-int('A')] = true;
l[int(txt[i])-int('A')] = cont;
break;
}
cont++;
}
}
}

void pintaLetras(const TLetras& l, const TArray& a){
for(unsigned i=0;i<MAX;i++){
if(a[i]==true){
cout <<"Distancia entre " << char(i+int('A')) << ": " << l[i] << endl;
}
}
}


Ejercicio 8
Código (cpp) [Seleccionar]
int sumaDiagonal(const TMatriz& m){
   unsigned i = j = 0, suma = 0;

   while((i<MAX)&&(j<MAX)){
      suma+=m[i][j];
      i++;
      j++;
   }
   return suma;
}


Ejercicio 9
Código (cpp) [Seleccionar]
#include <iostream>
using namespace std;

const unsigned M = 10;
typedef int TDatos[M][M];
struct TMatriz{
TDatos matriz;
unsigned f;
unsigned c;
};

void introDatos(TMatriz& m);
void puntosSilla(const TMatriz& m, bool& notiene);
int menorFila(const TMatriz& m, unsigned i);
int mayorCol(const TMatriz& m, unsigned j);

int main() {
TMatriz m;
bool notiene = true;

introDatos(m);
puntosSilla(m,notiene);

if(notiene){
cout << "La matriz no tiene ningun punto silla." << endl;
}

return 0;
}

void introDatos(TMatriz& m){
cout << "Introduzca numero de filas: ";
do{
cin >> m.f;
}while((m.f<=0)||(m.f>10));
cout << "Introduzca numero de columnas: ";
do{
cin >> m.c;
}while((m.c<=0)||(m.c>10));
cout << "Introduzca numeros en la matriz " << m.f << "x" << m.c << ": ";
for(unsigned i=0;i<m.f;i++){
for(unsigned j=0;j<m.c;j++){
cout << "m(" << i+1 << "," << j+1 << "): ";
cin >> m.matriz[i][j];
}
}
}

void puntosSilla(const TMatriz& m, bool& notiene){
int menor;
unsigned i,j;

for(i=0;i<m.f;i++){
menor = menorFila(m,i);
for(j=0;j<m.c;j++){
if((m.matriz[i][j]==menor)&&(menor==mayorCol(m,j))){
cout << "Punto Silla: (" << i+1 << "," << j+1 << ")" << endl;
notiene = false;
}
}
}
}

int menorFila(const TMatriz& m, unsigned i){
int menor = m.matriz[i][0];

for(unsigned j=1;j<m.c;j++){
if(m.matriz[i][j]<menor){
menor = m.matriz[i][j];
}
}
return menor;
}

int mayorCol(const TMatriz& m, unsigned j){
int mayor = m.matriz[0][j];

for(unsigned i=1;i<m.f;i++){
if(m.matriz[i][j]>mayor){
mayor = m.matriz[i][j];
}
}
return mayor;
}


Ejercicio 10
Código (cpp) [Seleccionar]
#include <iostream>
#include <string>
using namespace std;

bool permitida(const string& s);
bool tieneIniciales(const string& t, char c);

int main() {
string s,t;

cout << "Introduzca texto: ";
do{
cin >> s;
}while(!permitida(s));
t = s;
cout << "Las palabras que comienzan con alguna letra de " << t << " son: ";
while(s!="FIN"){
if((permitida(s))&&(tieneIniciales(t,s[0]))&&(s!=t)){
cout << s << " ";
}
do{
cin >> s;
}while(!permitida(s));
}
return 0;
}

bool permitida(const string& s){
bool res = true;

for(unsigned i=0;i<s.size();i++){
if((s[i]<'A')||(s[i]>'Z')){
res = false;
break;
}
}
return res;
}

bool tieneIniciales(const string& t, char c){
bool res = false;

for(unsigned i=0;i<t.size();i++){
if(t[i]==c){
res = true;
break;
}
}
return res;
}


Ejercicio 11
Código (cpp) [Seleccionar]
#include <iostream>
#include <string>
using namespace std;

const unsigned MAX_PAL_DIST = 20;
typedef string TArray[MAX_PAL_DIST];
struct TDatos{
TArray a;
unsigned n;
};

void contienePatron(const string& p, TDatos& datos);
bool permitida(const string& s);
bool contiene(const string& p, const string& s);
bool repetida(const string& s, const TDatos& datos);
void pintaPalabras(const TDatos& datos);

int main() {
TDatos datos;
string p;

do{
cout << "Introduzca patron: ";
cin >> p;
}while(!permitida(p));
datos.n = 0;
contienePatron(p,datos);
pintaPalabras(datos);

return 0;
}

void contienePatron(const string& p, TDatos& datos){
string s;

cout << "Introduzca texto terminado en 'FIN': ";
while((s!="FIN")&&(datos.n<MAX_PAL_DIST)){
do{
cin >> s;
}while(!permitida(s));
if((contiene(p,s))&&(!repetida(s,datos))){
datos.a[datos.n] = s;
datos.n++;
}
}
}

bool permitida(const string& s){
bool res = true;

for(unsigned i=0;i<s.size();i++){
if((s[i]<'A')||(s[i]>'Z')){
res = false;
break;
}
}
return res;
}

bool contiene(const string& p, const string& s){
unsigned i = 0, cont = 0;
bool res = false;

while((s[i]!=p[0])&&(i<s.size())){
i++;
}
while((cont<p.size())&&(i<s.size())){
if(s[i]==p[cont]){
res = true;
i++;
cont++;
}else{
res = false;
break;
}
}
return res;
}

bool repetida(const string& s, const TDatos& datos){
bool res = false;

for(unsigned i=0;i<datos.n;i++){
if(datos.a[i]==s){
res = true;
}
}
return res;
}

void pintaPalabras(const TDatos& datos){
for(unsigned i=0;i<datos.n;i++){
cout << datos.a[i] << " ";
}
}


Ejercicio 12
Código (cpp) [Seleccionar]
#include <iostream>
#include<string>
using namespace std;

const unsigned MAX = 50;
struct TFecha{
   unsigned dia,mes,anyo;
};
struct TProducto{
   unsigned codigo;
   string nombre;
   float precio;
   TFecha fecha_cad;
};
typedef TProducto TMedicamentos[MAX];
struct TFarmacia{
   TMedicamentos med;
   unsigned num;
};

void LeerProducto(TProducto& p){
   cout << "Introduzca codigo: ";
   cin >> p.codigo;
   cout << "Introduzca nombre: ";
   getline(cin,p.nombre);
   cout << "Introduzca precio: ";
   cin >> p.precio;
   cout << "FECHA: " << endl;
   cout << "Introduzca dia: ";
   do{
      cin >> p.fecha_cad.dia;
   }while((p.fecha_cad.dia<1)||(p.fecha_cad.dia>31));
   cout << "Introduzca mes: ";
   do{
      cin >> p.fecha_cad.mes;
   }while((p.fecha_cad.mes<1)||(p.fecha_cad.mes>12));
   cout << "Introduzca año: ";
   cin >> anyo;
}

void EscribirProducto(const TProducto& p){
   cout << "Codigo: " << p.codigo << endl;
   cout << "Nombre: " << p.nombre << endl;
   cout << "Precios: " << p.precio << endl;
   cout << "Fecha: " << p.fecha_cad.dia << "/" << p.fecha_cad.mes << "/" << p.fecha_cad.anyo << endl;
}

void inicializarFarmacia(TFarmacia& f){
   f.num = 0;
}

void insertarProducto(TFarmacia& f, const TProducto& p){
   f.med[f.num] = p;
   f.num++;
}

void BorrarProducto(TFarmacia& f, unsigned codigo){
   bool esta = false;
   unsigned i;
   for(i=0;i<f.num;i++){
      if(f.med[i].codigo == codigo){
         esta = true;
         break;
      }
   }
   if(esta){
      f.med[i] = f.med[f.num-1];
      f.num--;
   }else{
      cout << "No esta" << endl;
   }
}

void BuscarProductoCodigo(const TFarmacia& f, unsigned codigo, bool& encontrado, TProducto& p){
   encontrado = false;

   for(unsigned i=0;i<f.num;i++){
      if(f.med[i].codigo == codigo){
         p = f.med[i];
         encontrado = true;
         break;
      }
   }
}

void BuscarProductoNombre(const TFarmacia& f, const string& nombre, bool& encontrado, TProducto& p){
   encontrado = false;

   for(unsigned i=0;i<f.num;i++){
      if(f.med[i].nombre == nombre){
         p = f.med[i];
         encontrado = true;
         break;
      }
   }
}

void ListarFarmacia(const TFarmacia& f){
   for(unsigned i=0;i<f.num;i++){
      EscribirProducto(f.med[i]);
      cout << endl;
   }
}
A reader lives a thousand lives before he dies. The man who never reads lives only one

dakomt

#2
N = 1 + 4K
N = 2 + 4K
N = 3 + 4K
N = 4 + 4K


Te doy mejor esa pista... tu sabras que hacer con ella  ;D


KaL3o

#3
bigfu te estas complicando con tantos case :p

Vi el enunciado y dije a probar parece complicado... de alli al papel antes que al codigo, y despues de hacer  unos matachos (dibujos mal hechos) encontre la respuesta.

La solución esta en que tu dominas quien empieza. Hay ciertos numeros donde el usuario debe empezar primero... ahh me aburri de tanto escribir y termine haciendo el codigo jajajaja

Código (c++) [Seleccionar]

#include<iostream>
using namespace std;

int main()
{
   int num,turno=1,resto,aux;
   do
   {
       cout<<"Introduzca numero: ";
       cin>>num;
   }
   while(num<=0);
   if(num%4==1)
       turno=0;
   do
   {
       cout<<num<<" Objetos"<<endl;
       switch(turno)
       {
           case 0: do
                   {
                       cout<<"Quitar [1] [2] [3] objetos: ";
                       cin>>resto;
                   }
                   while(resto<1 || resto>3 || resto>num);
                   turno=2;
                   break;
           case 2: resto=4-resto;
                   cout<<"Computador quita "<<resto<<" objetos"<<endl;
                   turno=0;
                   break;
           case 1: for(int j=num-1;j>=num-3;j--)
                       if(j%4==1)
                           aux=j;
                   resto=num-aux;    
                   cout<<"Computador quita "<<resto<<" objetos"<<endl;
                   turno=0;
                   break;
       }
       num-=resto;
   }
   while(num!=0);
   cout<<"Computador Wins... user sucks!!!"<<endl;
}


Salu2 ;)
Todos los caminos se vuelven a juntar. Pero nunca de la misma forma.

satu

#4
Hola

Aquí lo tienes

Código (cpp) [Seleccionar]

#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;

int main()
{
   int turno, resta, num;

   srand(time(NULL));
   turno = rand() % 2;

   do
       {
       cout << "Introduce el numero de objetos: ";
       cin >> num;
       }
   while(num <= 0);

   while(num > 0)
       {
       cout << endl << "Quedan " << num << " objetos";

       if(turno)
           {
            do
                {
               cout << endl << endl << "Cuantos objetos quieres retirar? [1][2][3]: ";
               cin >> resta;
                }
            while(resta < 1  || resta > 3);
           num -= resta;
           turno = 0;
           }
       else
           {
           resta = rand() % 3 + 1;
           cout << endl << endl << "La maquina retira " << resta << " objetos" << endl;
           num -= resta;
           turno = 1;
           }
       }
   if(turno)
       cout << endl << endl << "ENHORABUENA. Has ganado :)" << endl << endl;
   else
       cout << endl << endl << "Has perdido :(" << endl << endl;

   cout << endl << "Pulse Enter para salir...";
   while(cin.get() != '\n');
   cin.get();
   return 0;
}


Saludos
Breakbeat como forma de vida

KaL3o

#5
satu brother creo que no consideraste que la maquina siempre debe ganar
Cita de: bigfu en 20 Julio 2011, 13:04 PM
En las condiciones del problema, es posible desarrollar un algoritmo para que siempre gane la máquina. Construir tal algoritmo.
Y tampoco pusiste restricción a que el usuario solo puede descontar de 1 a 3 objetos

Salu2 ;)
Todos los caminos se vuelven a juntar. Pero nunca de la misma forma.

satu

Cita de: KaL3o en 22 Julio 2011, 12:55 PM
satu brother creo que no consideraste que la maquina siempre debe ganar

Es cierto, no me fijé en eso

Cita de: KaL3o en 22 Julio 2011, 12:55 PM
Y tampoco pusiste restricción a que el usuario solo puede descontar de 1 a 3 objetos
Esto ya está corregido

Gracias por la corrección

Saludos
Breakbeat como forma de vida

bigfu

#7
Muchas gracias a los 3 por las respuestas, se agradece.
Sería ya mucho pedir que explicárais como lo habéis hecho?? :rolleyes: es que entiendo que es lo que hacen los programas, pero lo que no entiendo es el por qué. Llevo un rato dándole vueltas a las 2 soluciones y no consigo comprender algunas cosas.

Muchas gracias, de verdad.

EDIT: Vale, creo que el código de KaL3o lo medio entiendo ya. Según lo que he entendido, habría unos "casos base", que serían los siguientes: cuando el número de objetos sea 4, 3, 2 o 1. En el caso de que haya inicialmente un solo objeto, elegimos que empiece el usuario, caso en el que perdería. Por lo tanto, la computadora siempre debe restar de tal forma que deje un número de objetos cuyo resto sea 1 al dividir entre 4, de tal forma que al forzar ese resultado, el usuario llegue a ese único objeto final.

El código de satu me cuesta entenderlo un poco más, me pierdo con el sran() que utiliza...

Muchas gracias de nuevo.
A reader lives a thousand lives before he dies. The man who never reads lives only one

satu

#8
Hola

El srand se utiliza para la generación de números aleatorios, y después rand calcula el número aleatorio. Yo lo utilizo para que el turno al principio sea aleatorio y después lo utilizo para que la máquina reste los objetos aleatoriamente, claro que como dijo antes KaL3o no tiene en cuenta el número de objetos restantes para poder ganar.

Saludos
Breakbeat como forma de vida

KaL3o

Claro... mas importante aun que el codigo es la logica :)

Alli es cuando uno se acuerda de los profes cuando le  decian a uno Antes de ponerse a hacer el codigo, dibujen, imaginen y entiendan la logica

Bien como te decia para que la maquina siempre gane, se necesita tener en cuenta el turno del jugador.

A lo que yo me puse a dibujar :p (subiria la imagen de mis matachos, pero el escaner esta ocupado)

mmm... vaya es mas complicado explicarlo que dibujarlo jajajaja

Necesitas qeu el usuario juegue en determinados numeros, como cuando solo hay un objeto.

estos numeros son 1, 5, 9, 13... te das cuenta el incremento es de 4. Cuando tomas todos estos numeros y los divides entre 4 siempre te va a quedar de residuo 1 (tambien conocido como el modulo)

Lo que tienes que hacer es que el usuario solo pueda jugar cuando esten esas cantidades de numeros.

digamos que se elige el numero 12 para jugar, como el 12%4=0, entonces debo hacer que la maquina juegue primero y me convierta esos 12 objetos en 9 (puesto que 9%4=1, y el 9 es menor que 12)

Ahora el jugador puede restar 1,2 o 3. Si el resta 1 quedara en 8, y a nosotros nos conviene que el siguiente numero sea 5, asi que el computaador restara 3. Si el user resta 2 nosotros restaremos 2 para que la cantidad de objetos sea 5, y si el user resta 3 la maquina debera restar 1 para que quede el numero que nos conviene, el 5.
(cuando restamos estamos completando 4)

Biena ahora en el 5 juega el usuario por lo que puede restar 1, 2 o 3, nostros (la maquina) debera completar la resta para restar 4, asi el usuario quedara con la ultima ficha.

En si lo que hay es que forzar al usuario a jugar cuando la cantidad de objetos divida entre 4 tenga por residuo 1. Y despues de ello completar la resta de 4.

Trate de explicar lo mejor que pude. Si luego me acuerdo subo mis matachos que son mas entendibles :p

Salu2 ;)

En el codigo de satu el srand() es para generar numeros aleatorios, ya la linea completa esta asignando a resta un numero entre 1 y 3
Todos los caminos se vuelven a juntar. Pero nunca de la misma forma.