传送门:HDU4841 圆桌问题
Sample Input
2 3
2 4
Sample Output
GBBG
BGGB
我们事先肯定是无法得知哪些位置安排好人哪些位置安排坏人,所以只能模拟处死的过程,标记被处死人的编号。等模拟结束就知道哪些位置上应该安排好人,哪些位置应该安排坏人了。
#include
#include
#include
#include
#include
#include
#include
using namespace std;
const int MAXN=7e4;
queue<int> q;
int vis[MAXN];
int main()
{
int n,m;
while(cin>>n>>m) // 多组数据,cin不用判断文件末尾
{
for(int i=1;i<=2*n;i++) // 2*n个人全部入队列
q.push(i);
int cnt=1;
while(!q.empty()&&q.size()>n) //队列不为空且剩下人数大于n
{
int temp=q.front();
q.pop();
if(cnt==m) // 数到m处死
{
cnt=1; //重新计数
vis[temp]=1; //标记该位置
}
else // 不会被处死
{
cnt++; // 继续计数
q.push(temp); //回到队尾
}
}
cnt=0;
for(int i=1;i<=2*n;i++)
{
if(vis[i]==1) // 会被处死的位置安排坏人
cout<<"B";
else
cout<<"G";
cnt++;
if(cnt==50) // 题中要求50个字母为一行
{
cout<<"\n";
cnt=0;
}
}
if(cnt<50) // 最后一行不满 50个字母也要换行
cout<<"\n";
cout<<"\n"; // 相邻数据间留有一空行
while(!q.empty()) //清空队列中剩余人
q.pop();
memset(vis,0,sizeof(vis)); // 清空标记,批量初始化 vis数组为 0
}
return 0;
}
#include
#include
#include
#include
#include
#include
#include
using namespace std;
const int MAXN=7e4;
int vis[MAXN];
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m)) // 多组数据
{
int cnt=1,size=0,ind=1;
while(size<n) // 处死人数不足 n
{
if(!vis[ind]) // 该位置还有人在(未被处死)
{
if(cnt==m) // 数到 m处死
{
cnt=1; // 重新计数
vis[ind]=1; // 标记该位置人被处死
size++; // 处死人数加一
}
else
cnt++; //计数
}
if(ind==2*n) // 轮转到末尾,从头开始
ind=1;
else // 继续轮转
ind++;
}
cnt=0;
for(int i=1;i<=2*n;i++)
{
if(vis[i]==1) // 会被处死的位置安排坏人
printf("B");
else
printf("G");
cnt++;
if(cnt==50) // 题中要求50个字母为一行
{
printf("\n");
cnt=0;
}
}
if(cnt<50) // 最后一行不满 50个字母也要换行
printf("\n");
printf("\n"); // 相邻数据间留有一空行
memset(vis,0,sizeof(vis)); // 清空标记,批量初始化 vis数组为 0
}
return 0;
}
#include
const int MAXN=7e4;
char s[MAXN];
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
for(int i=1;i<MAXN;i++) // 初始全部是好人
s[i]='G';
int num=0,cnt=0;;
for(int i=1;num<n;i=(i%(2*n))+1) //轮转
{
if(s[i]=='B') //该位置的人已经被处死
continue;
cnt++;
if(cnt==m) //数到m
{
cnt=0; // 重新计数
s[i]='B'; // 该位置的人会被处死,安排坏人
num++; // 坏人数+1
}
}
for(int i=1;i<=2*n;i++)
{
printf("%c",s[i]);
if(i%50==0) // 每 50个换行
printf("\n");
}
if(2*n%50!=0) // 最后一行不到 50个
printf("\n");
printf("\n"); // 相邻数据换行
}
return 0;
}
传送门:HDU1062 Text Reverse
Sample Input
3
olleh !dlrow
m'I morf .udh
I ekil .mca
Sample Output
hello world!
I'm from hdu.
I like acm.
Hint
Remember to use getchar() to read ‘\n’ after the interger T, then you may use gets() to read a line and process it.
T个测试样例,每个样例给定一行包含若干单词的文本,每个单词用空格隔开,要求输出反转每个单词后的文本。
对于一行文本,边读边存,当碰到空格或者读到末尾,倒序输出存的单词,并清空存储空间。
注意看提示内容。要用读取输入T后的换行。
#include
#include
const int MAXN=1e3+5;
char s[MAXN],temp[MAXN];
int ind=0;
int main()
{
int T;
scanf("%d",&T);
getchar(); //读取输入T后的换行,避免下面的gets读到一个空串
while(T--)
{
gets(s); // 读取整行
ind=0;
int len=strlen(s);
for(int i=0;i<len;i++)
{
if(s[i]!=' ') // 不是空格,复制字母
temp[ind++]=s[i];
else // 碰到空格,说明一个单词结束
{
for(int j=ind-1;j>=0;j--) //反转输出
printf("%c",temp[j]);
printf(" "); // 输出空格
ind=0; // 清空ans数组
}
}
// 最后一个单词,末尾没有空格
for(int j=ind-1;j>=0;j--)
printf("%c",temp[j]);
printf("\n");
}
return 0;
}
#include
#include
#include
using namespace std;
string s,temp;
int main()
{
int T;
cin>>T;
cin.get(); //读取输入T后的换行,注意最好不要将 cin和 getchar()混合使用
while(T--)
{
temp="";
getline(cin,s); // 读取整行
int len=s.size();
for(int i=0;i<len;i++)
{
if(s[i]!=' ') // 不是空格,复制字母
temp+=s[i];
else // 碰到空格,说明一个单词结束
{
reverse(temp.begin(),temp.end());
cout<<temp<<" ";
temp="";
}
}
// 最后一个单词,末尾没有空格
reverse(temp.begin(),temp.end());
cout<<temp<<"\n";
}
return 0;
}
传送门:HDU1702 ACboy needs your help again!
Sample Input
4
4 FIFO
IN 1
IN 2
OUT
OUT
4 FILO
IN 1
IN 2
OUT
OUT
5 FIFO
IN 1
IN 2
OUT
OUT
OUT
5 FILO
IN 1
IN 2
OUT
IN 3
OUT
Sample Output
1
2
2
1
1
2
None
2
3
T个测试样例,每个样例第一行是整数N(命令数),以及单词“ FIFO”或“ FILO”。(“ FIFO”代表“先进先出”和“ FILO” 表示“先进先出”)。在接下来的N行中,每行是“ IN M”或“ OUT”(M代表整数)。对于“IN M”命令将执行入队列(栈)操作,对于OUT将执行出队列(栈)并输出操作。
用队列和栈执行给定操作即可。
#include
#include
#include
#include
using namespace std;
const int MAXN=1e3+5;
char ch[MAXN];
queue<int> q;
stack<int> s;
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
while(!q.empty()) // 清空队列
q.pop();
while(!s.empty()) // 清空栈
s.pop();
int n;
scanf("%d%s",&n,&ch);
if(ch[2]=='F') //FIFO
{
for(int i=0;i<n;i++) // n条命令
{
scanf("%s",&ch);
if(ch[0]=='I') // IN
{
int m;
scanf("%d",&m);
q.push(m); // 入队列
}
else // OUT
{
if(q.empty()) // 如果队列为空
printf("None\n");
else
{
printf("%d\n",q.front()); // 输出
q.pop(); // 出队列
}
}
}
}
else //FILO
{
for(int i=0;i<n;i++) // n条命令
{
scanf("%s",&ch);
if(ch[0]=='I') // IN
{
int m;
scanf("%d",&m);
s.push(m); // 入栈
}
else // OUT
{
if(s.empty()) // 栈为空
printf("None\n");
else
{
printf("%d\n",s.top()); // 输出
s.pop(); //出栈
}
}
}
}
}
return 0;
}
传送门:HDU1873 看病要排队
Sample Input
7
IN 1 1
IN 1 2
OUT 1
OUT 2
IN 2 1
OUT 2
OUT 1
2
IN 1 1
OUT 1
Sample Output
2
EMPTY
3
1
1
用三个优先队列来模拟三个医生,执行相应操作即可。
注意: 如果遇到两个优先权一样的病人的话,则选择最早来排队的病人。所以要自定义优先队列比较规则。
#include
#include
#include
using namespace std;
const int MAXN=1e3+5;
char s[MAXN];
int cnt=0;
struct patient{
int priority;
int id;
patient(int x,int y) //构造
{
priority=x;
id=y;
}
friend bool operator < (patient a, patient b) // 重载运算符,自定义比较规则
{
if(a.priority==b.priority) // 优先级相同,id小的优先,即先来的优先
return a.id>b.id;
else
return a.priority < b.priority; // 优先级不同,优先级高的优先
}
};
priority_queue<patient> q1; // 1号医生
priority_queue<patient> q2; // 2号医生
priority_queue<patient> q3; // 3号医生
int main()
{
int n;
while(~scanf("%d",&n)) // 多组测试
{
while(!q1.empty())
q1.pop();
while(!q2.empty())
q2.pop();
while(!q3.empty())
q3.pop();
id=0;
while(n--) // n个事件
{
scanf("%s",&s);
if(s[0]=='I') // IN
{
int a,b;
scanf("%d%d",&a,&b); // 挂号医生a,优先级为b
id++; // "IN A B"事件发生第K次时,进来的病人ID即为K
if(a==1)
q1.push(patient(b,id));
else if(a==2)
q2.push(patient(b,id));
else
q3.push(patient(b,id));
}
else // OUT
{
int a;
scanf("%d",&a);
if(a==1)
{
if(q1.empty())
printf("EMPTY\n");
else
{
printf("%d\n",q1.top().id);
q1.pop();
}
}
else if(a==2)
{
if(q2.empty())
printf("EMPTY\n");
else
{
printf("%d\n",q2.top().id);
q2.pop();
}
}
else
{
if(q3.empty())
printf("EMPTY\n");
else
{
printf("%d\n",q3.top().id);
q3.pop();
}
}
}
}
}
return 0;
}
朋友提供的思路:优先队列数组版
#include
#include
using namespace std;
const int MAXN=1e3+5;
char s[MAXN];
int id=0;
typedef pair<int,int> P; //first存优先级,second存id
struct cmp{
bool operator () (P p1,P p2)
{
if(p1.first==p2.first)
return p1.second>p2.second; // 按id从小到大排序
else
return p1.first<p2.first; //从优先级从大到小排序
}
};
priority_queue<P,vector<P>,cmp> q[4]; // 医生
int main()
{
int n;
while(~scanf("%d",&n)) // 多组测试
{
// 清空队列
for(int i=1;i<=3;i++)
while(!q[i].empty())
q[i].pop();
id=0;
while(n--) // n个事件
{
scanf("%s",&s);
if(s[0]=='I') // IN
{
int a,b;
scanf("%d%d",&a,&b); // 挂号医生a,优先级为b
id++; // "IN A B"事件发生第K次时,进来的病人ID即为K
q[a].push(P(b,id));
}
else // OUT
{
int a;
scanf("%d",&a);
if(q[a].empty())
printf("EMPTY\n");
else
{
printf("%d\n",q[a].top().second);
q[a].pop();
}
}
}
}
return 0;
}
传送门:HDU2648 Shopping
Sample Input
3
memory
kfc
wind
2
49 memory
49 kfc
48 wind
80 kfc
85 wind
83 memory
Sample Output
1
2
给定一个n和n个商店,然后给定一个m,在接下来的m天,每天n个商店价格会上涨s(注意是上涨s,不是上涨到s),问每天结束,"memory"这家商店排名是多少,这里的排名定义为比它价格高的商店个数+1。
利用map键唯一的特性,累计同一商店的价格,最后遍历map,统计价格大于"memory"的商店个数即可。
注意:本题描述并未说明是多组测试样例,但是不写while(cin>>n)对多组样例进行处理会WA。
#include
#include
#include
#include
#include
#include
using namespace std;
map<string,int> mp;
int main()
{
int n;
while(cin>>n) //多组样例,cin不用判断读到文件末尾
{
for(int i=0;i<n;i++) // n家商店
{
string store;
cin>>store;
mp[store]=0;
}
int m;
cin>>m;
for(int i=0;i<m;i++) // m天
{
for(int j=0;j<n;j++) // n家商店
{
int price;
string store;
cin>>price>>store;
mp[store]+=price; // 商店价格上涨price
}
int ans=0,num=mp["memory"];
map<string,int>::iterator it;
for(it=mp.begin();it!=mp.end();it++) //遍历n家商店
if(it->second>num) // 统计价格高于"memory"商店的个数
ans++;
cout<<ans+1<<"\n";
}
mp.clear(); //清空map
}
return 0;
}