TCP는 소켓 생성 후 데이터 전송 시에 주소 정보 따로 추가 안 한다.
하지만 UDP는 연결상태 유지하지 않으므로 데이터 전송마다 목적지 주소정보 추가 필요.
sendto() : 주소정보를 써 넣으면서 데이터를 전송recvfrom() : UDP 데이터 수신. 발신지 정보를 함께 반환.int main(int argc, char *argv[])
{
int serv_sock;
char message[BUF_SIZE];
int str_len;
socklen_t clnt_adr_sz;
struct sockaddr_in serv_adr, clnt_adr;
if(argc != 2) {
printf("Usage : %s <port>\n", argv[0]);
exit(1);
}
serv_sock=socket(PF_INET, SOCK_DGRAM, 0);
if(serv_sock == -1)
error_handling("UDP socket creation error");
memset(&serv_adr, 0, sizeof(serv_adr));
serv_adr.sin_family=AF_INET;
serv_adr.sin_addr.s_addr=htonl(INADDR_ANY);
serv_adr.sin_port=htons(atoi(argv[1]));
if(bind(serv_sock, (struct sockaddr*)&serv_adr, sizeof(serv_adr))==-1)
error_handling("bind() error");
while(1)
{
clnt_adr_sz=sizeof(clnt_adr);
str_len=recvfrom(serv_sock,message,BUF_SIZE,0,
(struct sockaddr*)&clnt_adr, &clnt_adr_sz);
sendto(serv_sock, message, str_len, 0,
(struct sockaddr*)&clnt_adr, clnt_adr_sz);
}
close(serv_sock);
return 0;
}
uecho_server.c
int main(int argc, char *argv[])
{
int sock;
char message[BUF_SIZE];
int str_len;
socklen_t adr_sz;
struct sockaddr_in serv_adr, from_adr;
if(argc!=3){
printf("Usage : %s <IP> <port>\n", argv[0]);
exit(1);
}
sock=socket(PF_INET, SOCK_DGRAM, 0);
if(sock==-1)
error_handling("socket() error");
memset(&serv_adr, 0, sizeof(serv_adr));
serv_adr.sin_family=AF_INET;
serv_adr.sin_addr.s_addr=inet_addr(argv[1]);
serv_adr.sin_port=htons(atoi(argv[2]));
while(1)
{
fputs("Insert message(q to quit): ", stdout);
fgets(message, sizeof(message), stdin);
if(!strcmp(message, "q\n") || !strcmp(message, "Q\n"))
break;
sendto(sock, message, strlen(message), 0,
(struct sockaddr*)&serv_adr, sizeof(serv_adr));
adr_sz=sizeof(from_adr);
str_len=recvfrom(sock,message,BUF_SIZE,0,
(struct sockaddr*)&from_adr, &adr_sz);
message[str_len]=0;
printf("Message from server: %s", message);
}
close(sock);
return 0;
}
uecho_clinet.c
UDP에선 sendto() 호출 전에 bind() 호출해서 주소 정보 할당해야 한다.
sendto() 호출 전까지 주소 정보 할당 안 됐다면 IP와 PORT 번호가 자동으로 할당된다. (일반적 구현법)

int MaxVal(int depth, int idx, vvi &triangle, vvi &dp)
{
if(dp[depth][idx]!=-1) return dp[depth][idx];
int originVal = triangle[depth][idx];
if(depth == size(triangle)-1) return originVal;
int leftMax = MaxVal(depth+1, idx, triangle, dp);
int rightMax = MaxVal(depth+1, idx+1, triangle, dp);
dp[depth][idx] = originVal + max(leftMax,rightMax);
return dp[depth][idx];
}
int solution(vector<vector<int>> triangle) {
// 하향식으로 왼쪽, 오른쪽 최대 재귀
int tri_sz = size(triangle);
vvi dp = vvi(tri_sz,vi(size(triangle[tri_sz-1]),-1));
return MaxVal(0,0,triangle,dp);
}
하향식으로 풀었더니 시간 초과됐다.
하향식이나 상향식이나 시간 복잡도 똑같을텐데?
int solution(vector<vector<int>> triangle) {
int tri_sz = size(triangle);
if(tri_sz == 1) return triangle[0][0];
vvi dp = vvi(tri_sz,vi(size(triangle[tri_sz-1]),0));
for(int i=tri_sz-1; 0<i; i--)
{
int w = size(triangle[i]);
for(int j=0; j<w; j++)
{
int sendVal = triangle[i][j] + dp[i][j];
if(j-1 >= 0) dp[i-1][j-1] = max(dp[i-1][j-1],sendVal);
if(j != w-1) dp[i-1][j] = max(dp[i-1][j],sendVal);
}
}
return dp[0][0]+triangle[0][0];
}
상향식으로 푸니 맞았다고 해줌
다른 풀이 중에 하향식 없는거 보니까
재귀로는 안되게 시간 조건을 빡빡하게 둔듯.
int solution(vector<vector<int>> t) {
int answer = 0;
for (int i = t.size() - 1; i > 0 ; i--)
{
for (int j = 0; j < t[i].size() - 1; j++)
{
if (t[i][j] > t[i][j + 1])
{
t[i - 1][j] += t[i][j];
}
else
{
t[i - 1][j] += t[i][j + 1];
}
}
}
answer = t[0][0];
return answer;
}
다른 사람 풀이.
오른쪽을 바로 비교하면서 위를 갱신하면
불필요한 공간이나 코드가 줄어든다.