#!/usr/bin/perl -I ../../../cgi-bin use CGI::Carp qw(fatalsToBrowser); use AIOC::HTML; use AIOC::SiteBase; use POSIX qw(strftime); $specDir = AIOC::SiteBase::specDir(); my $site = new AIOC::SiteBase("aioc", "$specDir/aioc.train", '', $site_news); $site->putHeader(); $site->putPageHeader("Tutorials"); print << "__END__";

Sitting or Standing?

Let's solve Sitting or Standing?. To prevent ourselves making time-wasting mistakes, it's important to plan ahead. What does our program have to do?

Sounds like a plan. Let's get started.

Skeleton Code

C C++
#include <stdio.h>

/*Declare variables*/

int main() {
	/*Read the input*/
	
	/*Calculate the answer*/
	
	/*Write the output*/
	
	/*Clean up!*/
	
	return 0;
}
#include <cstdio>

/*Declare variables*/

int main() {
	/*Read the input*/
	
	/*Calculate the answer*/
	
	/*Write the output*/
	
	/*Clean up!*/
	
	return 0;
}
Pascal
program Solution;

{Declare variables.}

begin
	{Read the input.}
	
	{Calculate the answer.}
	
	{Write the output.}
	
	{Clean up!}
end.

Now this is a little familiar. Yes, this is exactly the same template we started with for Addition. Indeed, the majority of informatics problems you'll encounter can be dealt with using a read-calculate-write approach. Ultimately, calculating the answer will usually be the most complex part of any solution. As we progress we'll want to spend more time thinking about this part and less time worrying about reading and writing to files. Given enough practice, we hope the latter will become second nature.

Reading the input

Just like before we declare a variable for the input file. In the 'Input' section we open it for reading. Later on we must properly close the file.

C, C++
/*Declare variables.*/
FILE* inputFile;
...
/*Read the input.*/
inputFile = fopen("sitin.txt","r");
...
/*Clean up!*/
fclose(inputFile);
Pascal
{Declare variables.}
var
inputFile: text;
...
{Read the input.}
assign(inputFile,'sitin.txt');
reset(inputFile);
...
{Clean up!}
close(inputFile);

Before we can read anything from the file we'll need variables to store the data in. Let's declare a few of those now.

C, C++
int r, s, nPeople, nSit, nStand;
Pascal
r, s, nPeople, nSit, nStand: longint;

Remember, it doesn't matter what you name your variables, so long as their names remind you what they represent. In this case I named the first two variables r and s, since those were the letters used in the problem statement. I named the next one nPeople because it represents the number of people arriving at the town hall. The last two variables, nSit and nStand, will be used to store our answers afterwards. Their names have the obvious meanings.

It takes just a few lines of code to read all the relevant variables from the file.

C, C++
fscanf(inputFile, "%d %d", &r, &s);
fscanf(inputFile, "%d", &nPeople);

The first line tells the computer several things. "fscanf(inputFile...)" tells it to read data from inputFile. "%d %d" tells the computer to expect two integers separated by a space. The rest of the line tells it to store these integers in r and s (in that order).

The second line reads another variable from the file and stores it to nPeople.

Pascal
readln(inputFile,r,s);
readln(inputFile,nPeople);

The first line tells the computer several things. "readln(inputFile...)" tells it to read an entire line from inputFile. The rest of the variable names between the parentheses tell it what to do with the data it reads - in this case, we're asking it to read in an integer and store it in r, and then to read in an integer and store it in s.

The second line reads another variable from the file and stores it to nPeople.

Before we go on you might want to give the code a quick test run. Compile it, make sure there's a file called sitin.txt in the same directory (containing three integers in the correct format), and run it. If it compiles properly and doesn't crash, we're doing good.

Calculating the answer

Now that we have all relevant inputs (r, s, nPeople), how are we going to calculate nSit and nStand? Let's start by examining the sample data.

InputOutput
7 12
100
84 16

What's happening here? In this particular case, there are 7 rows with 12 seats each, giving a total of 84 seats. When the 100 people arrive at the town hall, they all try to sit, and all the seats are taken by 84 people. The remaining 16 people are forced to stand. This suggests a straightforward approach: we fill all the seats and use subtraction to determine how many are left standing. That is:

nSit = r*s; //Seat as many as we can
nStand = nPeople - nSit; //The rest

However, there is another kind of case we need to consider. We have assumed that it is possible to fill all seats, but is this always possible?

InputOutput
7 12
80
80 0

Notice how in the above case there are 84 seats but only 80 of them are assigned. If we ran the previous code on this input we could recieve 84 -4, which is obviously wrong (what does "-4 people" even mean?). Clearly, if there are more than enough seats to accomodate everyone, then we want to perform a different set of code. These are even simpler:

nSit = nPeople; //Seat everyone
nStand = 0; //Nobody stands

When do we use each case? Clearly it depends on whether it is possible to seat everyone. Specifically, we want to compare nPeople to r*s and decide from this. It follows:

/*Calculate the answer*/
if (nPeople > r*s) {
	nSit = r*s;
	nStand = nPeople - nSit;
} else {
	nSit = nPeople;
	nStand = 0;
}

I'm assuming you have some familiarity with if statements. There's nothing daunting about them; they tell the computer how to decide between two sets of actions. In this example, the computer will ask itself whether nPeople is greater than r*s (that is, which case it's dealing with) and act accordingly. For us, understanding the above code is as simple as reading it aloud.

Writing the output

Just like before we declare a variable for the output file. In the 'Output' section we open it for writing. Later on we must properly close the file.

C, C++
/*Declare variables.*/
FILE* outputFile;
...
/*Write the output.*/
outputFile = fopen("sitout.txt","w");
...
/*Clean up!*/
fclose(outputFile);
Pascal
{Declare variables.}
var
outputFile: text;
...
{Write the output.}
assign(outputFile,'sitout.txt');
rewrite(outputFile);
...
{Clean up!}
close(outputFile);

Nearly done! All that remains is to write nSit and nStand to the file, separated by a space.

C, C++
fprintf(outputFile, "%d %d\n", nSit, nStand);
Pascal
writeln(outputFile,nSit,' ',nStand);

Having put all the code together, we have (hopefully) constructed a working solution to Sitting or Standing?, one which should score full marks. Unlike the previous problem, the full code hasn't been supplied, and this is deliberate. It is much more beneficial to type up the program ourselves than to simply copy and paste it from elsewhere; we certainly won't have that luxury in an AIO.

__END__ $site->putPageFooter(); # Always return true. 1;